[英]Passing delegate to linq query in EF Core
我有以下委托声明:
private Func<Employee, bool> _exclude;
然后在代码的其他地方,将其值设置为:
_exclude = (subject) =>
!subject.IsDeleted && subject.Location.Department.Company.GroupId.Equals(_groupId);
目的是在所有查询中重用过滤器。 如果我要像这样实现一个员工实例,这将很好地工作:
Employee theEmployee = db.Employees
.Include(e=>e.Location)
.ThenInclude(e => e.Department)
.ThenInclude(e => e.Company)
.Where(e => e.EmployeeId == EmployeeId && _exclude(e))
.FirstOrDefault();
但是,当我只想检索一个值(例如EmployeeId)时,它就会失败:
string employeeId = db.Employees
.Include(e=>e.Location)
.ThenInclude(e => e.Department)
.ThenInclude(e => e.Company)
.Where(e => e.EmployeeId == EmployeeId && _exclude(e))
.Select(e => e.EmployeeId)
.FirstOrDefault();
上面的方法无法在Func委托_exclude中产生NullReferenceException,因为subject.Location值为null,这意味着传递给委托的雇员没有按照Includes完全实现。
当需要成熟的Employee但无法进行投影查询时,它可以成功地实现Employee图的原因是什么?或者在这种情况下应如何构成查询?
我正在使用EF Core
是什么原因,当需要完整的Employee时却成功实现了Employee图,但无法进行投影查询
在这两种情况下, _exclude(e)
都不会转换为SQL,而是在内存中进行评估,并且在第二种情况下会失败,因为忽略了包含 ,并且缺少惰性加载支持。
尽可能使用Expression<Func<...>>
总是更好,因为它们会转换为SQL并在数据库端进行评估,因此包括无关紧要。
在您的情况下,更改_exclude
变量的类型(分配它的lambda语法保持不变)并在&&
上使用链接式Where
是很容易的:
private Expression<Func<Employee, bool>> _exclude;
(根据过滤器的语义,它实际上应该称为_include
或_filter
,但无论如何)
和
_exclude = (subject) =>
!subject.IsDeleted && subject.Location.Department.Company.GroupId.Equals(_groupId);
现在工作:
Employee theEmployee = db.Employees
.Include(e=>e.Location)
.ThenInclude(e => e.Department)
.ThenInclude(e => e.Company)
.Where(e => e.EmployeeId == EmployeeId)
.Where(_exclude)
.FirstOrDefault();
以及这个:
string employeeId = db.Employees
// not needed, but will not hurt if used, will be ignored anyway
//.Include(e=> e.Location)
//.ThenInclude(e => e.Department)
//.ThenInclude(e => e.Company)
.Where(e => e.EmployeeId == EmployeeId)
.Where(_exclude)
.Select(e => e.EmployeeId)
.FirstOrDefault();
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.