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

How to Explicit loading specific related entities for specific entities using Entity Framework?

我有两个数据库表:

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

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

您可以使用 SelectMany 在所有位置展平员工列表。然后你可以根据角色筛选

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

您可以 return SelectMany 中的匿名类型,它将包含 Location 属性,例如:

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

我为存储库模式的实现做了类似的事情。关键是在最后调用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();