C# 如何使用实体框架为特定实体显式加载特定的相关实体?

C# 如何使用实体框架为特定实体显式加载特定的相关实体?,c#,entity-framework,lazy-loading,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")); 我的问题是如

我有两个数据库表:

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"));
您可以在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"));

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

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

我为存储库模式的实现做了类似的事情。关键是在最后调用
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();
}
然后循环所有位置并加载引用。另一个选项是为您的案例编写显式的
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();

我为存储库模式的实现做了类似的事情。关键是在最后调用
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();
}
然后循环所有位置并加载引用。另一个选项是为您的案例编写显式的
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();

因此,您希望所有员工都具有主管角色,而不考虑位置吗?@Riv否,我只想为locations表中的所有位置加载具有主管角色的员工。当然,locations dataEF不支持部分加载的引用集合。因此,您需要决定是通过包含加载所有位置,还是单独查询想要的位置员工。因此,您希望所有员工都具有主管角色,而不管位置如何?@Riv No,我只想为locations表中的所有位置加载具有主管角色的人员,当然,locations dataEF并不支持部分加载的引用集合。因此,您需要决定是通过include加载所有位置,还是单独查询想要的位置人员。这只会加载没有位置数据的人员,我认为正如@grek40所说的“EF不支持部分加载的引用集合”@SimpleCode您需要整个Location实体还是特定属性?整个Location实体这只会加载没有locations数据的人员,我认为正如@grek40所说的“EF不支持部分加载的引用集合”@SimpleCode您需要整个位置实体还是特定属性?整个位置实体谢谢您的回答。我认为这是一个很好的实现方法谢谢您的回答。我认为这是一个很好的实现方法