【问题标题】:Regex.IsMatch() in dynamic linq动态 linq 中的 Regex.IsMatch()
【发布时间】:2020-12-06 17:08:09
【问题描述】:

如何在IQueryable 中调用Regex.IsMatch()? 我发现了同样的问题,但它不起作用 Invoking Regex.IsMatch() inside a dynamic linq query

首先我有

IQueryable Database = data.Verses.Select($"new {{ ID, {TextSearchType.ToString()} }}");

试过了

var searchResult = Database.Where(Parse());

public static LambdaExpression Parse()
{
    ParsingConfig.Default.CustomTypeProvider = new MyCustomTypeProvider();
    var options = RegexOptions.IgnoreCase;
    string compilableExpression = $"Regex.IsMatch({TextSearchType.ToString()}, \"(^| ){Keyword}($| )\", @0) == true";
    ParameterExpression parameter = Expression.Parameter(typeof(Verses));
    var DynamicExpression = DynamicExpressionParser.ParseLambda(new[] { parameter },
                                             null,
                                             compilableExpression,
                                             options);
    return DynamicExpression;
}
public class MyCustomTypeProvider : DefaultDynamicLinqCustomTypeProvider
{
    public override HashSet<Type> GetCustomTypes()
    {
        return new HashSet<Type>
                {
                    typeof(Object),
                    typeof(Boolean),
                    typeof(System.Text.RegularExpressions.Regex),
                    typeof(System.Text.RegularExpressions.RegexOptions),
                };
    }
}

TextSearchType 是 Verses 类中的属性名称。 我收到这个错误

“System.Linq.Queryable”类型上没有通用方法“Where” 与提供的类型参数和参数兼容。无类型 如果方法是非泛型的,则应提供参数。

这是我试图转换为 linq 动态的 linq 代码

var rx = new Regex("(^| )" + keyword + "($| )", RegexOptions.IgnoreCase);
var searchResult = Database.AsEnumerable()
            .Where(x => rx.IsMatch(x.AyahText)).ToList();

【问题讨论】:

  • 你查询的是什么类型的数据库?
  • 带有ef6代码的sql server。
  • 我不相信这是可能的。
  • 我想出了解决方案,我只是循环通过数据库然后 if (rx.IsMatch(verse)) SearchResultObj.Add(ayah);愚蠢的我,但无论如何感谢:)
  • 在您的示例中使用 StartsWith/EndsWIth/Contains 而不是正则表达式,例如((x.AyahText == keyword || x.AyahText.StartsWith(keyword+" ") || x.AyahText.EndsWith(" "+keyword) || x.AyahText.Contains(" "+keyword+" "))。

标签: c# linq dynamic


【解决方案1】:

您不能在 LINQ to Entities 中调用 IsMatch 或任何其他非 SQL 支持的函数(请参阅完整列表 here)。

为了做你想做的事,你有两个可能的选择(也许更多,但我现在知道两个):

  1. 通过原始过滤获取项目(不使用IsMatch),将结果转换为List,在查询结束时调用.ToList()。然后您可以通过 Regex.IsMatch 过滤集合。
    说实话,这不是一个更好的解决方案,我不会说我喜欢它。
  2. 创建一个存储过程并从c#调用它(官方文档here)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-06-26
    • 1970-01-01
    • 2011-05-21
    • 1970-01-01
    • 2011-04-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多