简体   繁体   English

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

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

I implemented the extension method to normalize a string described in this post: LINQ Where Ignore Accentuation and Case 我实现了扩展方法来规范化这篇文章中描述的字符串: LINQ Where Ignore Accentuation和Case

This method work like a charm if I do things like this: 如果我做这样的事情,这种方法就像一个魅力:

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

Now, I want to use it more generically by generating the predicate of the where clause dynamically. 现在,我想通过动态生成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);

The predicate will look like this: 谓词将如下所示:

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

For an unknown reason, when executed I got the following error message: 由于未知原因,执行时出现以下错误消息:

No applicable method 'RemoveDiacritics' exists in type 'String' “String”类型中不存在“RemoveDiacritics”的适用方法

But, this method actually works fine if I use it elsewhere. 但是,如果我在其他地方使用它,这种方法实际上可行。

Any ideas what is wrong here? 任何想法在这里有什么不对?

Note that the ToLower() works like a charm in this situation. 请注意, ToLower()在这种情况下就像魅力一样。

Thanks in advance for your help! 在此先感谢您的帮助!

EDIT 编辑

Here is the definition of the extension method: 以下是扩展方法的定义:

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 does not support extension methods. Dynamic Linq不支持扩展方法。 The reason for this is that Dynamic Linq uses reflection, and it is really hard to find the implementation of the extension method, and call it using reflection. 原因是Dynamic Linq使用反射,很难找到扩展方法的实现,并使用反射调用它。 So the authors of dynamic Linq didn't bother with it. 所以动态Linq的作者并没有为此烦恼。

So, you have to call the extension method like a regular static method: 因此,您必须像常规静态方法一样调用扩展方法:

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"));

can be replaced with 可以替换为

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

which is faster and doesn't bother with case. 这更快,不打扰案件。

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

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