C#中用于比较字符串数组的Contains方法

4
我想使用LINQ比较一个字符串字段和一个字符串数组,我已经编写了下面的扩展方法来进行比较,但它不能正确地工作。
 public static bool Contains(this string source, string[] keys)
    {
        foreach (var item in keys)
        {
            if (source.Contains(item))
                return true;
        }

        return false;
    }

这是我的查询内容:
string[] keys = key.Split('+');
        var pages = context.Pages.Where(x => x.Title.Contains(keys));

我收到的错误信息是:
LINQ to Entities 不识别方法 'Boolean Contains(System.String, System.String[])',且该方法无法转换为存储表达式。
3个回答

7

您不能像这样在LINQ中使用自定义的方法,但您可以尝试使用普通的LINQ操作符重写它:

string[] keys = key.Split('+');
var pages = context.Pages.Where(x => keys.Any(key => x.Title.Contains(key)));

如果那个方法不起作用,我怀疑在EF中基本上是不可行的。

1
谢谢@Jon Skeet,它起作用了 :) 但我想知道为什么我的方法不起作用。 - Saeed Hamed
@Jon Skeet 这在 EF Core 中不起作用,表达式没有被翻译。有什么想法吗? - Nexus
@Nexus:恐怕不行。我没有使用过EF Core的经验。 - Jon Skeet
@JonSkeet 不用担心,非常感谢。如果我没记错的话,在EF6中这个很好用,但是显然EF Core缺少了一些LINQ扩展功能。 - Nexus
这在最新版本中不再起作用了...正在尝试找出是什么时候出了问题以及如何修复...在 EF Core 5 中也无法工作,但我确定它在 3.1 中可以。 - Seabizkit

4
你在Where中编写的lambda表达式实际上是由EF评估并转换为SQL的。例如,当你写下以下代码时:
db.Pages.Where(x => x.Title == "Hello")

EF知道如何将生成的IQueryable<T>转换为类似以下内容的东西:
SELECT ... FROM Pages WHERE title = 'Hello'

同样地,它了解一些常见的方法和运算符,例如:

db.Pages.Where(x => x.Contains("Hello"))

EF知道将String.Contains翻译为:

SELECT ... FROM Pages WHERE title LIKE '%Hello%'

然而,当您使用自己的自定义方法与表达式一起使用时,EF不知道如何将该自定义方法翻译为SQL,这就是您看到的错误消息所抱怨的内容。


1

LINQ to Entities不识别方法'Boolean Contains(System.String, System.String[])',而且这个方法不能被翻译成存储表达式。

请注意,您的代码正在转换为SQL,如果我没有错的话,您的错误信息说:'Boolean Contains(System.String, 这个方法无法被翻译,这意味着这部分无法转换为SQL。如果将字符串强制转换为BIT,则可能会起作用。如果有人觉得我可能走错了方向,请告诉我。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接