我正在使用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);
提前致谢!吉列尔莫
答案 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);
}