简体   繁体   English

LINQ不能使用string.contains?

[英]LINQ can't use string.contains?

This is my code: 这是我的代码:

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

but I get: 但我得到:

Only arguments that can be evaluated on the client are supported for the String.Contains method. String.Contains方法仅支持可在客户端上计算的参数。

Why? 为什么? Can't I use .Contains() ? 我不能使用.Contains()

Try .IndexOf . 试试.IndexOf It is not LINQ that can't do Contains , it's LINQ to Entities and LINQ to SQL that can't. 它不是LINQ,不能做Contains ,它的LINQ to Entities和LINQ to SQL不能。

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

Why? 为什么?

LINQ uses deferred execution . LINQ使用延迟执行 This means it waits until you want to iterate over your query results before it does anything. 这意味着它等待您想要在执行任何操作之前迭代查询结果。 There are 3 main types of LINQ: LINQ有3种主要类型:

  1. LINQ to Objects - when your IEnumerable is already on the heap. LINQ to Objects - 当你的IEnumerable已经在堆上时。
  2. LINQ to Entities - when you want to query a database using Entity Framework. LINQ to Entities - 当您想使用Entity Framework查询数据库时。
  3. LINQ to SQL - when you want to query a database using LINQ to SQL. LINQ to SQL - 当您想使用LINQ to SQL查询数据库时。

Deferred execution in the context of the second 2 means that your query is not executed on the database until you enumerate the results in a foreach block, or invoke an enumeration method like .ToList , .ToArray , etc. Until then, your query is just stored as expression trees in memory. 在第二个2的上下文中延迟执行意味着您的查询不会在数据库中执行,直到您在foreach块中枚举结果,或调用枚举方法,如.ToList.ToArray等。在此之前,您的查询只是作为表达式树存储在内存中。

Your query would work just peachy if db.User was a collection in memory. 如果db.User是内存中的集合,那么您的查询将只是db.User However when the data is in a database, LINQ to Entities (or LINQ to SQL) must translate your expression trees to what it calls a "store expression" -- which is just fancy talk for "convert my LINQ expressions to SQL". 但是,当数据在数据库中时,LINQ to Entities(或LINQ to SQL)必须将表达式树转换为它所谓的“存储表达式” - 这对于“将我的LINQ表达式转换为SQL”来说只是花哨的讨论。

Now imagine you had a custom C# algorithm you wanted to use for your query, and you did something like this: 现在假设你有一个你想要用于查询的自定义C#算法,你做了类似这样的事情:

var result = db.User.Where(x => MyCustomMethod(x));

There is no way today that LINQ to Entities can convert your C# code into a SQL query (store expression). 今天LINQ to Entities无法将您的C#代码转换为SQL查询(存储表达式)。 It is the same with a lot of other C# methods you rely on daily. 每天依赖的许多其他C#方法也是如此。 It also does not support .ToLower , .ToUpper , .StartsWith , .EndsWith , etc. There is a limited number of C# methods that can be converted to store expressions, and .IndexOf just happens to be one of them. 它也不支持.ToLower.ToUpper.StartsWith.EndsWith等。可以转换为存储表达式的C#方法数量有限,而.IndexOf恰好就是其中之一。

However keep in mind that it is only the string object's Contains method that we are talking about here that is not supported for store expressions. 但是请记住,我们在这里讨论的只是字符串对象的Contains方法,这对于商店表达式是不支持的。 LINQ to Entities does support .Contains on IEnumerable s. LINQ to Entities确实支持IEnumerable.Contains The following is valid and will work with LINQ to Entities (not sure about LINQ to SQL): 以下是有效的,将与LINQ to Entities一起使用(不确定LINQ to SQL):

var idsIWantToFind = new[] { 1, 2, 3 };
var users = db.Where(x => idsIWantToFind.Contains(x.UserId));

The above is the equivalent of doing a SQL WHERE UserId IN (1, 2, 3) predicate. 以上相当于执行SQL WHERE UserId IN (1, 2, 3)谓词。

the problem is priority of inputs. 问题是投入的优先考虑。 for example: 例如:

a.Contains(b); a.Contains(b)中; or b.Contains(a); 或b。包含(a);

u'd better write: 你最好写:

p.Nickname.Contains(queryString) ...

instead of 代替

queryString.Contains(p.Nickname) ...

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

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