c# - Entity Framework Core 3.1.6 的动态查询构建问题
问题描述
我正在动态构建 LINQ 查询。我使用 EF Core 3.1.6(用于 SQL Server)。
我使用谓词创建了一个IQueryable
带有where()
子句的子句。
EF Core 能够翻译以下谓词表达式,并且查询按预期工作:
{p => ((p.Address != null) AndAlso p.Address.Contains(Convert("6152 Fames Ro", String)))}
但 EF Core 无法翻译以下谓词表达式:
{p => (((p.FirstName != null) AndAlso p.FirstName.Contains(Convert("fred", String))) OrElse ((p.MiddleName != null) AndAlso p.MiddleName.Contains(Convert("fred", String))))}
它抛出以下异常:
LINQ 表达式 'DbSet\r\n .Where(p => p.FirstName != null && p.FirstName.Contains("fred") || p.MiddleName != null && p.MiddleName.Contains("fred" ))' 无法翻译。以可翻译的形式重写查询,或通过插入对 AsEnumerable()、AsAsyncEnumerable()、ToList() 或 ToListAsync() 的调用显式切换到客户端评估。有关详细信息,请参阅https://go.microsoft.com/fwlink/?linkid=2101038。
我调查了以下问题:
- 从 dotnet Core 2.2.6 更改为 3.0.0 后出现 EF Linq 错误
- https://entityframeworkcore.com/knowledge-base/58166970/migrating-from-ef-core-2-to-ef-core-3
正如异常消息中所建议的,我尝试在决赛中做等AsEnumerable()
,但没有奏效。我想这将排除客户评估问题。ToList()
IQueryable
我确信我做错了什么;不知道是什么。
有人可以帮忙吗?如果需要,我可以提供更多信息。
解决方案
我找到了解决我的问题的方法。
谓词应按如下方式构造:
{p => (((p.FirstName != null) AndAlso p.FirstName.Contains(Convert("fred", String))) OrElse Invoke(p => ((p.MiddleName != null) AndAlso p.MiddleName.Contains(Convert("fred", String))), p))}
上述谓词工作正常。
为了解决这个问题,我做了 2 处更改:
- 从此转换以下扩展方法:
对此:public static Expression<Func<T, bool>> Or<T>(this Expression<Func<T, bool>> expr1, Expression<Func<T, bool>> expr2) { return Expression.Lambda<Func<T, bool>> (Expression.OrElse(expr1.Body, expr2.Body), expr1.Parameters); }
public static Expression<Func<T, bool>> Or<T>(this Expression<Func<T, bool>> expr1, Expression<Func<T, bool>> expr2) { var invokedExpr = Expression.Invoke(expr2, expr1.Parameters); return Expression.Lambda<Func<T, bool>> (Expression.OrElse(expr1.Body, invokedExpr), expr1.Parameters); }
- 改变了方式,我由此构造了常量表达式:
对此:var member = Expression.Property(parameter, propertyInfo); var filterValueConstant = Expression.Convert(Expression.Constant(convertedValue), propertyType);
var underlyingTypeConstExpr = Expression.Constant(convertedValue); var filterValueConstant = Expression.Convert(underlyingTypeConstExpr, propertyType);
这解决了我的问题。但我仍然不知道为什么旧谓词不起作用。
推荐阅读
- git - "git log" "tag:" 跨 repos 不一致
- c++ - 将静态库链接到共享:标头中的枚举类 -> 针对未定义符号重定位 R_X86_64_PC32
- php - 在 Laravel 中显示 cron 工作
- reactjs - 幕后 React JS 中的单击事件有效吗?
- vba - ComboBox Enter 事件从对象浏览器中消失
- python - 为什么我的自动编码器没有使用其代码的所有元素?
- node.js - node.js - 错误:第一次连接时无法连接到服务器 [localhost:27017] [MongoNetworkError: connect ECONNREFUSED 127.0.0.1:27017]
- c# - 如何拦截mongodb c#驱动程序2.x的AsQueryable()?
- php - 如何将数据从 Python 发送到 Android 应用程序
- mysql - 如何按列显示结果?