【问题标题】:Null Value when converting to IQueryable with Entity Framework使用实体框架转换为 IQueryable 时的空值
【发布时间】:2012-11-16 21:46:27
【问题描述】:

我正在使用 EF5,并且我有一个带有 GetById 方法的通用存储库,该方法可以接收像这样需要的包含属性:

public virtual T GetByIdIncluding(long id, params Expression<Func<T, object>>[] includeProperties)
{
    IQueryable  <T> query = DbContext.Set<T>().Find(id) as IQueryable<T>;

    foreach (var includeProperty in includeProperties)
    {
        query = query.Include(includeProperty);
    }

    return query.FirstOrDefault();
}

DbContext.Set&lt;T&gt;().Find(id) 返回正确的对象,但是当我将其转换为 IQueryable 时,变量查询的值变为空。

为什么?如何仅选择具有参数发送的 Id 的实体和参数发送的所有包含项?

使用示例:

var houses = Uow.Types.GetByIdIncluding(id, tt => tt.Houses);

提前致谢!吉列尔莫

【问题讨论】:

    标签: c# linq entity-framework linq-to-entities entity-framework-5


    【解决方案1】:

    DbContext.Set&lt;T&gt;().Find(id) 返回单个实体。

    IQueryable&lt;T&gt;DbContext.Set&lt;T&gt;()


    在您按 ID 选择单个实体后,您无法包含某些属性。在包含一些属性后,您也不能使用DbSet&lt;T&gt;.Find,因为结果将是IQueryable&lt;T&gt;。您可以做什么 - 稍后按 id 包含属性和过滤结果:

    public static IQueryable<T> Including(
                              params Expression<Func<T, object>>[] includeProperties)
    {            
        IQueryable<T> query = DbContext.Set<T>();
    
        foreach (var includeProperty in includeProperties)    
            query = query.Include(includeProperty);    
    
        return query;
    }
    

    后来:

    var types = Uow.Types.Including(tt => tt.Houses)
                         .SingleOrDefault(tt => tt.Id == id);
    

    您还可以在具体的存储库类中创建方法GetByIdIncluding(而不是在通用存储库中):

    public static Foo GetByIdIncluding(long id, 
                     params Expression<Func<Foo, object>>[] includeProperties)
    {
        return Including(includeProperties).SingleOrDefault(f => f.Id == id);
    }
    

    顺便说一句考虑使用延迟加载(默认启用)。

    【讨论】:

    • 我知道,这就是我要解决的问题,但不知道如何解决。
    • 感谢您的回答!我唯一不喜欢的是,我需要从数据库中检索所有内容以便稍后过滤并只获取一个......
    • 使用IQueryable 将在数据库中进行结果过滤 - 只会返回一个结果
    • 哦,我明白了……因为运行将被推迟。谢谢!很好的答案!
    【解决方案2】:

    http://msdn.microsoft.com/en-us/library/gg696418%28v=vs.103%29.aspx DbSet.Find 方法返回一个实体,而不是您的实体的 IQueryable。在调用 Find 方法之前尝试在 Set 上设置 Include。

    【讨论】:

    • 与之前的响应相同...当我将 Find 移到最后一行时,无法解析符号 Find
    【解决方案3】:

    您需要将Find 移到循环之后:

    public virtual T GetByIdIncluding(long id, params Expression<Func<T, object>>[] includeProperties)
    {
        var query = DbContext.Set<T>();
    
         foreach (var includeProperty in includeProperties)
         {
             query = query.Include(includeProperty);
         }
    
        return query.Find(id);
    }
    

    【讨论】:

    • 如果我使用该代码,它会在 foreach 内的行中抱怨无法将 IQueryable 转换为 DbSet。如果我用 IQueryable 替换 var,那么 foreach 就可以,但它说在最后一行找不到符号 Find。
    • 顺便说一句,没有办法先过滤吗?因为我不想从数据库中检索所有包含所有实体的所有实体,所以最后只使用其中一个。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-18
    • 2012-08-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多