В T-SQL у вас может быть такой запрос:
SELECT * FROM Users WHERE User_Rights IN ("Admin", "User", "Limited")
Как бы вы повторили это в запросе LINQ to Entities? Это вообще возможно?
источник
В T-SQL у вас может быть такой запрос:
SELECT * FROM Users WHERE User_Rights IN ("Admin", "User", "Limited")
Как бы вы повторили это в запросе LINQ to Entities? Это вообще возможно?
Вы должны перевернуть его с точки зрения того, как вы думаете об этом. Вместо того, чтобы делать «in», чтобы найти права пользователя текущего элемента в предварительно определенном наборе применимых прав пользователя, вы спрашиваете предварительно определенный набор прав пользователя, содержит ли оно применимое значение текущего элемента. Это точно так же, как вы найдете элемент в обычном списке в .NET.
Есть два способа сделать это с помощью LINQ, один использует синтаксис запроса, а другой использует синтаксис метода. По сути, они одинаковы и могут использоваться взаимозаменяемо в зависимости от ваших предпочтений:
Синтаксис запроса:
var selected = from u in users
where new[] { "Admin", "User", "Limited" }.Contains(u.User_Rights)
select u
foreach(user u in selected)
{
//Do your stuff on each selected user;
}
Синтаксис метода:
var selected = users.Where(u => new[] { "Admin", "User", "Limited" }.Contains(u.User_Rights));
foreach(user u in selected)
{
//Do stuff on each selected user;
}
Моим личным предпочтением в этом случае может быть синтаксис метода, потому что вместо назначения переменной я мог бы выполнить foreach над анонимным вызовом, например так:
foreach(User u in users.Where(u => new [] { "Admin", "User", "Limited" }.Contains(u.User_Rights)))
{
//Do stuff on each selected user;
}
Синтаксически это выглядит более сложным, и вам нужно понять концепцию лямбда-выражений или делегатов, чтобы действительно выяснить, что происходит, но, как вы можете видеть, это сжимает код в достаточной степени.
Все сводится к вашему стилю кодирования и предпочтениям - все три моих примера делают одно и то же немного по-разному.
Альтернативный способ даже не использует LINQ, вы можете использовать тот же синтаксис метода, заменив «where» на «FindAll», и получите тот же результат, который также будет работать в .NET 2.0:
foreach(User u in users.FindAll(u => new [] { "Admin", "User", "Limited" }.Contains(u.User_Rights)))
{
//Do stuff on each selected user;
}
Этого должно хватить вашей цели. Он сравнивает две коллекции и проверяет, имеет ли одна коллекция значения, совпадающие со значениями в другой коллекции.
источник
Если вы используете VS2008 / .net 3.5, см. Совет № 8 Алекса Джеймса: http://blogs.msdn.com/alexj/archive/2009/03/26/tip-8-writing-where-in-style -queries-используя-LINQ к entities.aspx
В противном случае просто используйте метод array.Contains (someEntity.Member).
источник
Я пойду на Inner Join в этом контексте. Если бы я использовал содержащуюся, она повторялась бы 6 раз, несмотря на то, что есть только одно совпадение.
Недостатки Содержит
Предположим, у меня есть два списка объектов.
Используя Contains, он будет искать каждый элемент списка 1 в списке 2, что означает, что итерация будет выполняться 49 раз !!!
источник
Это может быть возможным способом прямого использования методов расширения LINQ для проверки предложения in.
источник
Я также пытался работать с SQL-IN-подобной вещью - запросом к Entity Data Model . Мой подход - построитель строк для составления большого OR-выражения. Это ужасно уродливо, но я боюсь, что сейчас это единственный путь.
Теперь хорошо, это выглядит так:
Работа с GUID в этом контексте : Как вы можете видеть выше, всегда есть слово «GUID» перед GUID ifself во фрагментах строки запроса. Если вы не добавите это,
ObjectQuery<T>.Where
выдается следующее исключение:Нашел это на форумах MSDN, может быть полезно иметь в виду.
Матиас
... с нетерпением ждем следующей версии .NET и Entity Framework, когда все станет лучше. :)
источник
Альтернативный метод ответа BenAlabaster
Прежде всего, вы можете переписать запрос следующим образом:
Конечно, это более «многословно» и боль писать, но все равно работает.
Так что, если бы у нас был какой-нибудь служебный метод, который бы облегчал создание такого рода выражений LINQ, мы были бы в бизнесе.
с помощью служебного метода вы можете написать что-то вроде этого:
Это создает выражение, которое имеет тот же эффект, что и:
Но что более важно на самом деле работает против .NET 3.5 SP1.
Вот сантехническая функция, которая делает это возможным:
Я не буду пытаться объяснить этот метод, кроме как сказать, что он по существу создает выражение предиката для всех значений, используя valueSelector (то есть p => p.User_Rights), и объединяет эти предикаты OR, чтобы создать выражение для полного сказуемое
Источник: http://blogs.msdn.com/b/alexj/archive/2009/03/26/tip-8-writing-where-in-style-queries-using-linq-to-entities.aspx
источник
Реальный пример:
источник
Шутки в сторону? Вы, ребята, никогда не использовали
источник
Checks = NumValues * NumRows
. Поскольку это расчет типа M * N, если любой из них мал, то время для выполнения каждой необходимой проверки также будет небольшим. Я добавил ограничение, чтобы cjm30305 знал, как настроить тестовую среду, в которой показывается, почему его решение плохое.where new[] { 1, 2, 3 }.Contains(x)
меньше сравненийwhere (x == 1 || x == 2 || x == 3)
?