LINQ不能使用string.contains?

时间:2013-11-05 14:30:40

标签: c# .net linq linq-to-sql linq-to-entities

这是我的代码:

string queryString = "Marco".ToLower();
utenti = db.User.Where(p => 
        queryString.Contains(p.Nickname.ToLower()) ||
            queryString.Contains(p.Nome.ToLower()) ||
            queryString.Contains(p.Cognome.ToLower())).ToList();

但我明白了:

  

String.Contains方法仅支持可在客户端上计算的参数。

为什么呢?我不能使用.Contains()吗?

2 个答案:

答案 0 :(得分:29)

试试.IndexOf。它不是LINQ,不能做Contains,它是LINQ to Entities,而LINQ to SQL则不能。{/ p>

string queryString = "Marco";
utenti = db.User.Where(p => 
    queryString.IndexOf(p.Nickname, StringComparison.OrdinalIgnoreCase) >= 0 ||
        queryString.IndexOf(p.Nome, StringComparison.OrdinalIgnoreCase) >= 0 ||
        queryString.IndexOf(p.Cognom, StringComparison.OrdinalIgnoreCasee) >= 0)
.ToList();

<强>为什么吗

LINQ使用deferred execution。这意味着它等待您想要在执行任何操作之前迭代查询结果。 LINQ有三种主要类型:

  1. LINQ to Objects - 当你的IEnumerable已经在堆上时。
  2. LINQ to Entities - 当您想使用Entity Framework查询数据库时。
  3. LINQ to SQL - 当您想使用LINQ to SQL查询数据库时。
  4. 在第二个2的上下文中延迟执行意味着在foreach块中枚举结果或调用.ToList之类的枚举方法之前,不会对数据库执行查询,{{在此之前,您的查询只是作为表达式树存储在内存中。

    如果.ToArray是内存中的集合,那么您的查询只会起作用。但是,当数据在数据库中时,LINQ to Entities(或LINQ to SQL)必须将表达式树转换为它所谓的“存储表达式” - 这对于“将我的LINQ表达式转换为SQL”只是一种奇特的说法。 / p>

    现在假设你有一个你想要用于查询的自定义C#算法,你做了类似这样的事情:

    db.User

    今天LINQ to Entities无法将您的C#代码转换为SQL查询(商店表达式)。每天依赖的许多其他C#方法也是如此。它也不支持var result = db.User.Where(x => MyCustomMethod(x)); .ToLower.ToUpper.StartsWith等。可以转换为存储表达式的C#方法数量有限,{{ 1}}碰巧就是其中之一。

    但是请记住,我们在这里讨论的只是字符串对象的.EndsWith方法,而商店表达式不支持这种方法。 LINQ to Entities支持.IndexOf上的Contains。以下是有效的,将与LINQ to Entities一起使用(不确定LINQ to SQL):

    .Contains

    以上相当于执行SQL IEnumerable谓词。

答案 1 :(得分:-1)

问题是输入的优先级。 例如:

a.Contains(B);或b.Contains(a);

你最好写一下:

p.Nickname.Contains(queryString) ...

而不是

queryString.Contains(p.Nickname) ...