1

我正在使用 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 时,变量查询的值变为空。

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

使用示例:

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

提前致谢!吉列尔莫

4

3 回答 3

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);
}

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

于 2012-11-16T21:52:47.400 回答
0

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

于 2012-11-16T21:54:50.410 回答
-1

您需要Find在循环之后移动 to:

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);
}
于 2012-11-16T22:01:21.043 回答