我有两个数据库表:
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"));
我的问题是如何为所有位置的主管角色的相关员工实现显式加载(我不需要如上所述的特定人员)?
答案 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();