使用Entity Framework转换为IQueryable时的空值

时间:2012-11-16 21:46:28

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

我正在使用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<T>().Find(id)返回正确的对象,但当我使用IQueryable进行转换时,变量查询的值变为null。

为什么呢?如何仅选择具有由参数发送的Id的实体以及由参数发送的所有包含?

使用示例:

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

提前致谢!吉列尔莫

3 个答案:

答案 0 :(得分:1)

DbContext.Set<T>().Find(id)返回单个实体。

IQueryable<T>DbContext.Set<T>()


按ID选择单个实体后,您不能包含某些属性。此外,在您添加一些属性后,您无法使用DbSet<T>.Find,因为结果将为IQueryable<T>。您可以做什么 - 包括属性和稍后按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);
}

BTW 考虑使用延迟加载(默认情况下已启用)。

答案 1 :(得分:0)

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

答案 2 :(得分:-1)

您需要将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);
}