[英]Entity Framework Plus - is it possible to share entities between different queries?
[英]Entity Framework Share Queries
我不太清楚该如何措辞,因此我将解释我的情况。
我有一个场景,在EmploymentHistory
表上有一个TerminationDate
字段,该字段可以为null或将来的日期。 EmploymentHistory
联接到一个Employees
表,它是一个1:M关系,其中一个Employee
可以拥有多个EmploymentHistory
记录。 该Employees
表联接到许多不同的地方,例如Users
表,该表代表Employees
可以登录的前端门户。
我经常只需要抓住在职员工。 处于活动状态的SQL逻辑是WHERE TerminationDate IS NULL OR TerminationDate >= GETDATE()
。 因此,如果TerminationDate为null或在以后设置。
因此,在EF中,我有以下查询:
// Grab all Active Employees context.Employees.Where(e => e.EmploymentHistory.Any(eh => eh.TerminationDate == null || eh.TerminationDate >= DateTime.Today).ToList();
// Get all Users context.Users.Where(u => u.Employee.EmploymentHistory.Any(eh => eh.TerminationDate == null || eh.TerminationDate >= DateTime.Today).ToList();
等等
该逻辑显示在大约5个不同的位置。 我如何共享EmploymentHistory.Any(eh => eh.TerminationDate == null || eh.TerminationDate >= DateTime.Today
,当基础导航道具可能不同时, EmploymentHistory.Any(eh => eh.TerminationDate == null || eh.TerminationDate >= DateTime.Today
的逻辑部分尝试过与Expression<Func<T, bool>>
但我认为我有解决方案,如果我可以使所有需要此实体的实体都从Base继承,并且可以始终假设有一个名为Employee的导航道具坐在那里,而Base是我的T
尝试一种扩展方法,EF Core只能在客户端进行评估,而不能在服务器端进行评估。
您可以为EmploymentHistory
编写一个表达式: Expression<Func<EmploymentHistory, bool>> activeEmployee = eh => eh.TerminationDate == null || eh.TerminationDate >= DateTime.Today;
Expression<Func<EmploymentHistory, bool>> activeEmployee = eh => eh.TerminationDate == null || eh.TerminationDate >= DateTime.Today;
并像这样使用它:
context.Employees.Where(e => e.EmploymentHistory.Any(activeEmployee)).ToList();
和
context.Users.Where(u => u.Employee.EmploymentHistory.Any(activeEmployee)).ToList();
。
这并不是代码的大幅减少,但是却减少了很多输入,甚至在由于某种原因需要更改逻辑并且不想在任何地方都更改逻辑的情况下甚至更好。
有很多方法可以做到这一点。 使用SQL Server和EF,您可以
我在较旧版本的EF中尝试了选项一,花了很长时间才能完成。 表现不佳,我再也没有尝试过。 不过,在新版本的EF中,这似乎变得越来越容易,因此欢迎您尝试一下。
选项2可能会在性能和准确性之间达到最佳平衡,因为您可以优化视图查询,然后仍然贪婪地加载数据以获得最佳效率。
选项3与选项2的工作原理非常相似,并且使用最简单的C#代码,但是效率将不如以前那样高,因为它必须单独处理而不是汇总处理列。
有时,我发现您必须使用具体化的信息,并且它确实提供了绝对最佳的性能,因为在运行时没有添加任何计算。 但是,您可能会面临数据不同步的风险,因此,我仅将其保留在性能至关重要的最严重情况下。
这@Rounder在他@WeskerTyrant的答复意见中引用的错误这里现在已经解决了在EF核心。
因此,您可以执行以下操作:
Expression<Func<T, bool>> IsActiveEmployee =
eh => eh.TerminationDate == null ||
eh.TerminationDate >= DateTime.Today
然后像这样调用它:
context.Users.AsQueryable().Where(IsActiveEmployee).ToList();
注意添加了.AsQueryable()
,它允许.Where()
接受一个Expression
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.