繁体   English   中英

在linq查询中使用C#扩展方法作为谓词

[英]Use C# extension method as predicate in linq query

我实现了扩展方法来规范化这篇文章中描述的字符串: LINQ Where Ignore Accentuation和Case

如果我做这样的事情,这种方法就像一个魅力:

employee.AsQueryable().Where(t=>t.Text.ToLower().RemoveDiacritics().Contains("ced"));

现在,我想通过动态生成where子句的谓词来更一般地使用它。

var values = filters.Select(f => f.Value is string && f.IgnoreAccent
                               ?((string)f.Value).RemoveDiacritics()
                               :f.Value).ToArray();

// Create a predicate expression
string predicate = filter.ToExpression(filters);

// Use the Where method of Dynamic Linq to filter the data
queryable = queryable.Where(predicate, values);

谓词将如下所示:

(Text.ToLower().RemoveDiacritics().Contains(@0))

由于未知原因,执行时出现以下错误消息:

“String”类型中不存在“RemoveDiacritics”的适用方法

但是,如果我在其他地方使用它,这种方法实际上可行。

任何想法在这里有什么不对?

请注意, ToLower()在这种情况下就像魅力一样。

在此先感谢您的帮助!

编辑

以下是扩展方法的定义:

public static class StringExtension
{
    public static string RemoveDiacritics(this String s)
    {
        String normalizedString = s.Normalize(NormalizationForm.FormD);
        StringBuilder stringBuilder = new StringBuilder();

        for (int i = 0; i < normalizedString.Length; i++)
        {
            Char c = normalizedString[i];

            if (CharUnicodeInfo.GetUnicodeCategory(c) != UnicodeCategory.NonSpacingMark)
                stringBuilder.Append(c);
        }

        return stringBuilder.ToString();
    }
}

Dynamic Linq不支持扩展方法。 原因是Dynamic Linq使用反射,很难找到扩展方法的实现,并使用反射调用它。 所以动态Linq的作者并没有为此烦恼。

因此,您必须像常规静态方法一样调用扩展方法:

var values = filters.Select(f => f.Value is string && f.IgnoreAccent
                           ?StringExtensions.RemoveDiacritics((string)f.Value)
                           :f.Value).ToArray();
employee.AsQueryable().Where(t=>t.Text.ToLower().RemoveDiacritics().Contains("ced"));

可以替换为

employee.AsQueryable().Where(t=>t.Text.Equals("ced", StringComparison.OrdinalIgnoreCase));

这更快,不打扰案件。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM