entity-framework-core - 如何将运行时参数传递给 EF Core 谓词表达式
问题描述
在使用 EF Core 的应用程序中,我试图通过创建可重用的谓词表达式库来消除查询代码的重复。但是,我正在为接受运行时参数的谓词而苦苦挣扎。
让我们假设父子关系中有 2 个简单的实体类:
public class Parent
{
public double Salary { get; set; }
public ICollection<Child> Children { get; set; }
}
public class Child
{
public double Salary { get; set; }
}
我可以使用像这样的常规 EF Core 查询来检索所有有孩子收入高于他们的父母的父母:
return Context.Set<Parent>()
.Where(parent => parent.Children.Any(child =>
child.Salary > parent.Salary));
如果我想为上述查询创建一个可重用的谓词,我想它可能看起来像这样:
private Expression<Func<Child, Parent, bool>> EarnsMoreThanParent = (Child child, Parent parent) => child.Salary > parent.Salary;
上面的谓词编译OK,但我还没有找到任何使用它的方法。问题是如何在运行时将父实体传递给它。这不编译:
return _context.Set<Parent>()
.Where(parent => parent.Children.Any(child =>
EarnsMoreThanParent(child, parent));
我知道我将Expression<>
andFunc<>
语法混为一谈,但我认为这是一个相对常见的要求,必须是可能的。
谢谢
解决方案
您可以尝试像这样包装整个表达式
private Expression<Func<Parent, bool>> EarnsMoreThanParent =
(Parent parent) => parent.Children.Any(child => child.Salary > parent.Salary)
然后用于整个 Where
return _context.Set<Parent>().Where(EarnsMoreThanParent);
你的代码的问题是在.Where(parent => parent.Children.Any(child => EarnsMoreThanParent(child, parent))
整个表达式里面是一个表达式。因此,您的方法EarnsMoreThanParent
不会被调用,因为它是Where
表达式的一部分,EF 会尝试将其解析为表达式并且会失败。
但是,是的,如果您需要将几个这样的条件与不同的条件结合起来,OR
它可能无法正常工作,Where(EanrsMoreThanParent).Where(SomeOtherCondition)
并且所有这些条件都将被翻译成AND
推荐阅读
- bazel - Bazel:输出目录的 genrule
- kotlin - DynamoDBMapper 加载无法实例化 Kotlin 数据类
- excel - 使用带有日期过滤器的 VBA-Excel 从 SQL Server 中提取数据 - 不工作
- java - Android应用程序登录屏幕未加载
- c# - 通过变量减少`if`的数量
- python - os.openpty() Operation not permitted after os.seteuid() from root to a user
- proxy - dataProvider 的“react-admin”代理问题
- javascript - 如何使用 AngularJS 中的用户输入发布到 DOM 中的现有 JSON 数据?
- html - 如何
标签在被删除后仍然可以在 HTML5 脚本中使用吗? - delphi-xe2 - ONVIF:什么是聚焦/聚焦的命令?