E-B*_*Bat 1 .net c# linq entity-framework entity-framework-core
我有以下委托声明:
private Func<Employee, bool> _exclude;
Run Code Online (Sandbox Code Playgroud)
然后在我的代码中的其他地方,我将其值设置为:
_exclude = (subject) =>
!subject.IsDeleted && subject.Location.Department.Company.GroupId.Equals(_groupId);
Run Code Online (Sandbox Code Playgroud)
目标是在所有查询中重用过滤器。如果我要实现这样的员工实例,这很好用:
Employee theEmployee = db.Employees
.Include(e=>e.Location)
.ThenInclude(e => e.Department)
.ThenInclude(e => e.Company)
.Where(e => e.EmployeeId == EmployeeId && _exclude(e))
.FirstOrDefault();
Run Code Online (Sandbox Code Playgroud)
但是当我只想检索单个值时它失败了,例如,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();
Run Code Online (Sandbox Code Playgroud)
由于subject.Location值为null,因此上述在Func 委托_exclude 中无法生成NullReferenceException ,这意味着传递给委托的员工未按照Includes 完全实现。
当需要一个成熟的员工但投影查询失败时,它成功实现员工图的原因是什么,或者在这种情况下应该如何组合查询?
我正在使用 EF Core
当需要一个成熟的员工但投影查询失败时,它成功实现员工图的原因是什么
在这两种情况下,_exclude(e)都没有转换为 SQL,而是在内存中计算,并且在第二种情况下失败,因为忽略包含和缺乏延迟加载支持。
Expression<Func<...>>在可能的情况下使用总是更好,因为它们被转换为 SQL 并在数据库端进行评估,因此包含无关紧要。
在您的情况下,很容易更改_exclude变量的类型(分配它的 lambda 语法保持不变)并使用 chainedWhere代替 on &&:
private Expression<Func<Employee, bool>> _exclude;
Run Code Online (Sandbox Code Playgroud)
(基于过滤器语义,它应该真正被称为_includeor _filter,但无论如何)
和
_exclude = (subject) =>
!subject.IsDeleted && subject.Location.Department.Company.GroupId.Equals(_groupId);
Run Code Online (Sandbox Code Playgroud)
现在这有效:
Employee theEmployee = db.Employees
.Include(e=>e.Location)
.ThenInclude(e => e.Department)
.ThenInclude(e => e.Company)
.Where(e => e.EmployeeId == EmployeeId)
.Where(_exclude)
.FirstOrDefault();
Run Code Online (Sandbox Code Playgroud)
还有这个:
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();
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
911 次 |
| 最近记录: |