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.
Why? Can't I use .Contains()
?
Contains(t.Id)). ToList();
Select(x => new { x, count = x. tags. Count(tag => list. Contains(tag)) }) .
Try .IndexOf
. It is not LINQ that can't do Contains
, it's LINQ to Entities and LINQ to SQL that can't.
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. This means it waits until you want to iterate over your query results before it does anything. There are 3 main types of LINQ:
IEnumerable
is already on the heap.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.
Your query would work just peachy if db.User
was a collection in memory. 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".
Now imagine you had a custom C# algorithm you wanted to use for your query, and you did something like this:
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). It is the same with a lot of other C# methods you rely on daily. 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.
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. LINQ to Entities does support .Contains
on IEnumerable
s. The following is valid and will work with LINQ to Entities (not sure about 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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With