基于Entity Framework Core实现动态Like查询表达式的报错问题解决
第一个错误(lambda参数数量不正确)修复
你在ContainsFilter的代码里存在一个疏漏:你创建了参数表达式但没有保留引用传递给Expression.Lambda方法。对比你可正常运行的IsEqualsFilter代码就能发现,正确写法是先把ParameterExpression单独存为变量,构造完主体表达式后,把这个参数变量传给Lambda方法。
同时为了兼容后续的客户端评估场景,不建议直接调用DbFunctionsExtensions.Like,改用原生string.Contains方法即可,修改后的GenerateExpression方法如下:
public override Expression<Func<TModel, bool>> GenerateExpression<TModel>( string propertyName, object value) { // 单独保留参数表达式的引用 ParameterExpression parameterExpression = Expression.Parameter(typeof(TModel), "e"); Expression expression = parameterExpression; char[] chArray = new char[1] { '.' }; foreach (string propertyOrFieldName in propertyName.Split(chArray)) { expression = Expression.PropertyOrField(expression, propertyOrFieldName); } var containsMethod = typeof(string).GetMethod(nameof(string.Contains), new[] { typeof(string) })!; ConstantExpression constantExpression = Expression.Constant(value?.ToString(), typeof(string)); var containsCall = Expression.Call(expression, containsMethod, constantExpression); return Expression.Lambda<Func<TModel, bool>>(containsCall, parameterExpression); }
第二个错误(客户端评估不支持Like方法)说明
DbFunctionsExtensions.Like是EF Core专门为服务端SQL翻译设计的方法,本身没有实现内存中执行的逻辑,所以当查询切换到客户端(内存)评估时,调用这个方法就会抛出异常。
改用string.Contains的优势是:
- 当查询在EF Core上下文执行时,EF会自动将
string.Contains翻译成LIKE '%xxx%'的SQL语句,完全满足服务端查询需求 - 当查询切换到客户端内存评估时,
string.Contains是字符串原生方法,可直接执行不会报错,完美兼容Blazor组件客户端过滤的场景。
如果确实需要支持_、%等自定义通配符匹配,可额外加分支判断逻辑:服务端查询用Like,客户端查询自行实现通配符匹配逻辑即可,常规包含查询需求用string.Contains已完全够用。
内容的提问来源于stack exchange,提问作者Enrico
相关产品推荐
相关产品推荐

