linq - LINQ EF Core 3.0 中的重大更改。使用表达式
问题描述
在我的应用程序中,我有一些使用相同重复逻辑的查询:
var someThings = context.table1
.where(SomeLogic)
.ToList();
使用 EF Core 2.1,我可以将此逻辑封装在具有所有这些表达式的层中:
public static Expression<Func<MyObject, bool>> SomeLogic =>
myObject => myObject.CreationDate.Date == DateTime.Now.Date
&& (myObject.Whatever.HasValue || myObject.MoreWhatever);
现在我发现这是在记忆中评估的,这很糟糕。
如果我这样做:
var someThings = context.table1
.where(myObject =>
myObject.CreationDate.Date == DateTime.Now.Date
&& (myObject.Whatever.HasValue || myObject.MoreWhatever))
.ToList();
然后在数据库中评估查询,但我将一些逻辑放在错误的层中。
我试图Expression
用一个函数或任何其他工具代替,但我没有找到办法。
有没有办法像我以前一样将查询的逻辑封装在一个层中,但保留 EF 规则以便仍然可以在数据库中评估该查询?
谢谢。
解决方案
这个答案解释了为什么你需要一个“真实的”表达式而不仅仅是一个 Lambda 。创建的表达式可以在任何地方创建并作为参数传递给执行查询的函数。
这个答案应该指导你需要走的路。你只需要用whatever.hasvalue...stuff替换这两个虚拟表达式
var param = Expression.Parameter(typeof(MyObject), nameof(MyObject));
// myObject.CreationDate.Date == DateTime.Now.Date
Expression dateExpression = Expression.Equal(Expression.Constant(DateTime.Now),
Expression.PropertyOrField(param, "CreationDate"));
var dummyExpression1 = Expression.Equal(Expression.Constant(1), Expression.Constant(1));
var dummyExpression2 = Expression.Equal(Expression.Constant(1), Expression.Constant(1));
// && (myObject.Whatever.HasValue || myObject.MoreWhatever)
Expression orExpression = Expression.Or(dummyExpression1, dummyExpression2);
Expression allConditions = Expression.And(dateExpression, orExpression);
//myObject =>
Expression myExpression = Expression.Lambda<Func<MyObject, bool>>(allConditions, param);
var someThings = context.table1
.where(myExpression)
.ToList();
Expression.PropertyOrField 给我带来了最大的麻烦。如果您有嵌套结构,则需要遍历数据结构并调用 Expression.PropertyOrField,第一个参数是上一次调用 Expression.PropertyOrField 的结果。
推荐阅读
- json - 如何在 Laravel 中接收单引号 JSON
- visualization - 如何将 vis.js 与地图一起使用
- vb.net - 调用 VB.Net 共享方法 frpm .NET Core 项目引发运行时异常 - 在 vb.net dll 中调用方法时
- javascript - 如何将音频流上传到节点
- android - 为什么我的 android 应用程序用户界面的某些部分被裁剪了?
- php - 连接变量后字符串(url)中的不可见空格
- java - 这种序列化格式叫什么?
- javascript - 如何在 javascript 的 for 循环中访问对象属性?
- mongodb - Java 应用程序无法识别我在 MongoDB 数据库中的集合。
- docusignapi - Docusign eventNotification 失败并出现错误 400