【问题标题】:Expression.Like alternative for filtering based on text in c#Expression.Like 替代基于 c# 中的文本进行过滤
【发布时间】:2021-06-13 18:50:17
【问题描述】:

我们没有某种 Expression.Like 在 c# 中。因此,作为替代方案,我正在做以下工作:

private static readonly MethodInfo StringContains = typeof(string).GetMethod("Contains", new[] { typeof(string) });

然后将其与如下表达式一起使用:

var contExpressions = new List<Expression>();
var equals = nonNullValues.Select(value =>
                               (Expression) Expression.Call(left, StringContains, Expression.Constant(value, typeof(string)))).ToList();
                           contExpressions.AddRange(equals);

但是这种比较是区分大小写的。我希望表达式忽略大小写。

作为替代方案,我尝试使用 indexof 方法,如下所示:

private static readonly MethodInfo StringContainsIgnoreCase = typeof(string).GetMethod("IndexOf", new[] { typeof(string), typeof(StringComparison) });

并与表达式一起使用:

var equals = nonNullValues.Select(value =>
                            Expression.NotEqual(Expression.Call(left, StringContainsIgnoreCase, Expression.Constant(value, typeof(string)), Expression.Constant(StringComparison.OrdinalIgnoreCase)), Expression.Constant(-1))).ToList();
                        contExpressions.AddRange(equals);

然后尝试将最终表达式设为:

var expression = Expression.Lambda<Func<T, bool>>(contExpressions.Count == 1 ? contExpressions[0] : contExpressions.Aggregate(Expression.Or), parameter);

这适用于某些情况,但对于其他情况,它会引发异常:

无法翻译 LINQ。无法翻译。以可翻译的形式重写查询,或通过插入对 AsEnumerable()、AsAsyncEnumerable()、ToList() 或 ToListAsync() 的调用显式切换到客户端评估。

谁能帮助我哪里出错?我如何使用表达式执行不区分大小写的包含检查? 提前致谢

【问题讨论】:

  • this 有帮助吗?
  • 为什么不在所有内容上使用:sSomeString.ToLower() 以忽略大小写?
  • @JesseChunn 在生成表达式时真的有可能吗,Expression.NotEqual 将期望表达式,因此无法在其上调用字符串方法

标签: c# linq .net-core expression asp.net-core-3.1


【解决方案1】:

我能够让这个工作如下:

private static readonly MethodInfo StringContainsIgnoreCase =typeof(DbFunctionsExtensions).GetMethod(nameof(DbFunctionsExtensions.Like), new[] { Expression.Property(null, typeof(EF).GetProperty(nameof(EF.Functions)) ??throw new InvalidOperationException()).Type, typeof(string), typeof(string)
    });

然后使用下面的表达式:

var equals = nonNullValues.Select(value =>
                        Expression.Call(null, StringContainsIgnoreCase, Expression.Property(null, typeof(EF), nameof(EF.Functions)), left, Expression.Constant($"%{value}%", typeof(string)))).ToList();
                    contExpressions.AddRange(equals);

当您需要一个表达式来执行字符串不区分大小写的包含工作时,这就像魅力一样。

【讨论】:

    猜你喜欢
    • 2018-06-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-17
    • 2021-10-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多