Ответ 1
Попробуйте .IndexOf
. Это не 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();
Почему?
LINQ использует отсроченное исполнение. Это означает, что он ждет, пока вы не захотите повторить результаты запроса до того, как он что-нибудь сделает. Существует 3 основных типа LINQ:
- LINQ to Objects - когда ваш
IEnumerable
уже находится в куче. - LINQ to Entities - когда вы хотите запросить базу данных с помощью Entity Framework.
- LINQ to SQL - при запросе базы данных с использованием LINQ to SQL.
Отсроченное исполнение в контексте второго 2 означает, что ваш запрос не выполняется в базе данных до тех пор, пока вы не перечислите результаты в блоке foreach
или не вызовите метод перечисления, такой как .ToList
, .ToArray
и т.д. До тех пор ваш запрос просто хранится в виде деревьев выражений в памяти.
Ваш запрос будет работать просто peachy, если db.User
был коллекцией в памяти. Однако, когда данные находятся в базе данных, LINQ to Entities (или LINQ to SQL) должны преобразовывать деревья выражений в то, что он вызывает "выражение хранилища" - это просто причудливый разговор для "конвертировать мои выражения LINQ в SQL".
Теперь представьте, что у вас был пользовательский алгоритм С#, который вы хотели использовать для своего запроса, и вы сделали что-то вроде этого:
var result = db.User.Where(x => MyCustomMethod(x));
Сегодня нет возможности LINQ to Entities преобразовать ваш код С# в запрос SQL (выражение хранилища). То же самое происходит с множеством других методов С#, на которые вы полагаетесь ежедневно. Он также не поддерживает .ToLower
, .ToUpper
, .StartsWith
, .EndsWith
и т.д. Существует ограниченное количество методов С#, которые могут быть преобразованы для хранения выражений, а .IndexOf
просто является одним из них.
Однако имейте в виду, что речь идет только о методе строкового объекта Contains
, который не поддерживается для выражений store. LINQ to Entities поддерживает .Contains
на IEnumerable
s. Следующие действия действительны и будут работать с LINQ to Entities (не уверены в LINQ to SQL):
var idsIWantToFind = new[] { 1, 2, 3 };
var users = db.Where(x => idsIWantToFind.Contains(x.UserId));
Вышеупомянутый эквивалент выполнения предиката SQL WHERE UserId IN (1, 2, 3)
.