如何使用Entity Framework显式加载特定实体的特定相关实体?

时间:2017-10-24 10:05:10

标签: c# entity-framework lazy-loading

我有两个数据库表:

1)地点,其中有很多员工

2)员工,其中包含许多角色

如果我只想加载具有特定位置主管角色的相关人员,我会这样做:

  var location = dbContext.Locations.Find(locationId);
  dbContext.Entry(location).Collection(b => b.Staffs).Query().Where(s => s.Roles.Any(r => r.Name=="Supervisor"));

我的问题是如何为所有位置的主管角色的相关员工实现显式加载(我不需要如上所述的特定人员)?

2 个答案:

答案 0 :(得分:1)

您可以使用SelectMany在所有位置展平Staff列表。然后,您可以根据角色进行过滤

dbContext.Locations.SelectMany(b => b.Staffs).Where(s => s.Roles.Any(r => r.Name=="Supervisor"));

您可以在SelectMany中返回一个包含位置属性的匿名类型,例如:

dbContext.Locations.SelectMany(x => x.Staffs, (x, Staffs) => 
                   new { locationID = x.LocationID, SomeOtherProperty = x.OtherProperty , Staff = Staffs })
                  .Where(y => y.Staff.Roles.Any(z => z.Name == "Supervisor"));

答案 1 :(得分:1)

我为我们的存储库模式实现做了类似的事情。关键是最后调用Load

我们有

public virtual void Load<TOut>(T entity, Expression<Func<T, ICollection<TOut>>> loadExpression, Expression<Func<TOut, bool>> filter) where TOut : class
{
    Context.Entry(entity).Collection(loadExpression).Query().Where(filter).Load();
}

因此,对于您的情况,您可以尝试

dbContext.Entry(location).Collection(b => b.Staffs).Query()
    .Where(s => s.Roles.Any(r => r.Name=="Supervisor")).Load();

然后遍历所有位置并加载引用。另一种选择是为您的案例编写明确的Linq2Entities查询。

var locationWithStaff = (from location in dbContext.Locations
                         select new
                         {
                             location,
                             Staffs = (from staff in location.Staffs
                                       where staff.Roles.Any(r => r.Name=="Supervisor")
                                       select staff).ToList()
                          }).ToList();