C# 将委托传递给EF Core中的linq查询
我有以下代表声明:C# 将委托传递给EF Core中的linq查询,c#,.net,entity-framework,linq,entity-framework-core,C#,.net,Entity Framework,Linq,Entity Framework Core,我有以下代表声明: private Func<Employee, bool> _exclude; 目标是在所有查询中重用过滤器。如果我要像这样具体化一个雇员实例,那么这很好: Employee theEmployee = db.Employees .Include(e=>e.Location) .ThenInclude(e => e.Department) .ThenInclude(e => e.Company) .Where(e
private Func<Employee, bool> _exclude;
目标是在所有查询中重用过滤器。如果我要像这样具体化一个雇员实例,那么这很好:
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();
由于subject.Location值为null,这意味着传递给代理的员工未按照Includes完全物化,因此上述操作无法在Func委托_exclude中生成NullReferenceException
当需要一名正式员工但投影查询失败时,是什么原因导致它成功地实现了员工图,或者在这种情况下应该如何组合查询
我正在使用EF核心
当需要一名正式员工,但投影查询失败时,它成功实现员工图的原因是什么
在这两种情况下,\u exclude(e)
都不会转换为SQL,而是在内存中进行计算,在第二种情况下,它会失败,因为存在延迟加载和缺少延迟加载支持
在可能的情况下,最好使用表达式
,因为它们被转换为SQL并在数据库端进行计算,所以包含不重要
在您的情况下,很容易更改\u exclude
变量的类型(分配变量的lambda语法保持不变),并在&&
上使用chainedWhere
:
private Expression<Func<Employee, bool>> _exclude;
现在,这项工作:
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();
当需要一名正式员工,但投影查询失败时,它成功实现员工图的原因是什么
在这两种情况下,\u exclude(e)
都不会转换为SQL,而是在内存中进行计算,在第二种情况下,它会失败,因为存在延迟加载和缺少延迟加载支持
在可能的情况下,最好使用表达式
,因为它们被转换为SQL并在数据库端进行计算,所以包含不重要
在您的情况下,很容易更改\u exclude
变量的类型(分配变量的lambda语法保持不变),并在&&
上使用chainedWhere
:
private Expression<Func<Employee, bool>> _exclude;
现在,这项工作:
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();
检查数据,查看你要经过的员工的位置,我认为发生的事情是没有为你的员工附加位置employees@Zinov,每个员工都有一个位置,它是后端的必填字段。请记住,对于正式员工来说,它工作得很好,如果不是的话,也应该失败。使用
Func
而不是Expression
?@IvanStoev,事实上不是。检查数据,查看您要经过的员工的位置,我想发生的事情是,没有为您的员工附加位置employees@Zinov,每个员工都有一个位置,它是后端的必填字段。请记住,对于正式员工来说,它工作得很好,如果不是的话,也应该失败。有没有理由使用Func
而不是Expression
?@IvanStoev,事实上没有。