首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >DbSet.FirstOrDefault()?

DbSet.FirstOrDefault()?
EN

Stack Overflow用户
提问于 2011-11-21 22:30:16
回答 5查看 20.6K关注 0票数 9

我想这么做,但它说我不能用FirstOrDefault,

代码语言:javascript
复制
public static int GetId(this Context db, Type type, string name)
{
    return db.Set(type).FirstOrDefault(x => x.Name == name).Id;
}

错误是“__System.Data.Entity.DbSet”不包含“FirstOrDefault”的定义,也找不到接受“System.Data.Entity.DbSet”类型的第一个参数的扩展方法“FirstOrDefault”(您缺少使用指令还是程序集引用)

然后我尝试了这个Cast方法,但是给出了一个错误,不能为'WindowStyle'类型的对象创建一个非泛型的DbSet (顺便说一下,WindowStyle是从下面的DomainEntity继承的),

代码语言:javascript
复制
var set = db.Set(type).Cast<DomainEntity>();
return set.FirstOrDefault(x => x.Name == name).Id;

这是课程,

代码语言:javascript
复制
public class DomainEntity
{
    public virtual int Id { get; set; }
    public virtual string Name { get; set; }
}
EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2011-11-22 19:34:29

这个答案可能对您没有帮助,这取决于您如何“动态”情况下,您调用这个方法,基本上,如果您知道类型在编译时是否。如果您知道它,您可以编写一个泛型方法来代替:

代码语言:javascript
复制
public static class MyExtensions
{
    public static int? GetId<TEntity>(this Context db, string name)
        where TEntity : DomainEntity
    {
        return db.Set<TEntity>()
            .Where(x => x.Name == name)
            .Select(x => (int?)x.Id)
            .FirstOrDefault();
    }
}

我已经将它更改为一个投影,因为如果只需要Id,则不需要加载完整的实体。您可以让数据库做选择属性的工作,以提高性能。此外,如果数据库中的名称没有匹配,则返回一个可空int。

您可以在代码中如下所示:

代码语言:javascript
复制
int? id = db.GetId<WindowStyle>("abc");

如您所见,对于此解决方案,您必须在编译时指定WindowStyle类型。

这假设DomainEntity不是模型的一部分(没有DbSet<DomainEntity>),而是实体的基类。否则,保罗·凯斯特的解决方案就会更容易。

编辑

或者,您也可以尝试以下方法:

代码语言:javascript
复制
public static class MyExtensions
{
    public static int? GetId(this Context db, Type entityType, string name)
    {
        return ((IQueryable<DomainEntity>)db.Set(entityType))
            .Where(x => x.Name == name)
            .Select(x => (int?)x.Id)
            .FirstOrDefault();
    }
}

并称之为:

代码语言:javascript
复制
int? id = db.GetId("abc", someType);

如果someType不从DomainEntity继承,它将在运行时抛出一个异常。通用版本将在编译时检查这一点。所以,如果你喜欢第一个版本的话。

票数 8
EN

Stack Overflow用户

发布于 2013-04-28 15:35:49

也许你失踪了

代码语言:javascript
复制
using System.Linq;
票数 29
EN

Stack Overflow用户

发布于 2011-11-21 22:57:17

第一个构造无法工作,因为您使用的是非泛型DbSet,因此不能应用FirstOrDefault扩展方法,后者只适用于泛型。听起来你已经明白了,因为你已经在尝试获得非通用的DbSet。使用Cast()方法所获得的错误是由于试图将DbSet强制转换为DbSet造成的。这是不允许的,因为如果是这样的话,就可以向DbSet (WindowsStyle以外的对象)添加不符合规则的成员。另一种说法是,DbSets不支持协方差,因为DbSets允许添加。

我想你得另找办法去做你想做的事。以这种方式混合LINQ和继承显然是有问题的。既然定义了基本类型,并且只处理基类型上可用的属性,那么为什么不直接查询基类型呢?

代码语言:javascript
复制
    public static int GetId(this Context db, string name)
    {
        return db.DomainEntities.FirstOrDefault(x => x.Name == name).Id;
    }

您可能担心不同类型之间的名称冲突,但您可能可以从这个开始,查看派生类型关联,以验证您正在查看的是正确的类型。处理此问题的一种方法是向DomainEntity定义中添加类型标志。

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8219435

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档