Есть ли способ создать предложение not in, как это было бы в SQL Server в Linq to Entities?
Предложение NOT IN в LINQ to Entities
Ответы (5)
Если вы используете коллекцию в памяти в качестве фильтра, вероятно, лучше всего использовать отрицание Contains (). Обратите внимание, что это может не сработать, если список слишком длинный, и в этом случае вам нужно будет выбрать другую стратегию (см. Ниже для использования стратегии для полностью ориентированного на БД запроса).
var exceptionList = new List<string> { "exception1", "exception2" };
var query = myEntities.MyEntity
.Select(e => e.Name)
.Where(e => !exceptionList.Contains(e.Name));
Если вы исключаете на основе другого запроса к базе данных, использование Except
может быть лучшим выбором. (Вот ссылка на поддерживаемые расширения Set в LINQ to Entities)
var exceptionList = myEntities.MyOtherEntity
.Select(e => e.Name);
var query = myEntities.MyEntity
.Select(e => e.Name)
.Except(exceptionList);
Это предполагает сложную сущность, в которой вы исключаете определенные в зависимости от некоторого свойства другой таблицы и хотите, чтобы имена сущностей не исключались. Если вам нужна вся сущность, вам нужно будет создать исключения как экземпляры класса сущности, чтобы они удовлетворяли оператору равенства по умолчанию (см. docs).
Except
производит ужасный SQL. Contains
- это метод, который следует использовать здесь: myEntities.MyEntity.Select(e => e.Name ).Where(x => !exceptionList.Contains(x))
.
- person Gert Arnold; 10.08.2013
UNION ALL
предложениями, где n - количество элементов в exceptionList
. Я просто пробовал с EF 6.1, так что дело не в том, что он улучшился или что-то в этом роде. В EF 4.1 то же самое, поэтому я просто не понимаю, почему этот ответ вообще был принят. Ответ, предлагающий Contains
, правильный. Я думаю, вы использовали Except
с другим IQueryable
, поэтому EF смогла перевести его в SQL EXCEPT
. А ты?
- person Gert Arnold; 06.10.2014
IQueryable
с Except
. Таким образом, все выражение содержит отображенные объекты и может быть переведено в SQL EXCEPT
. Использование Except
со списком в памяти отличается. @tvanfosson Я знаю, что есть какое-то исправление: stackoverflow.com/q/24534217/861716. Except
(со списком в памяти) будет вызывать слишком глубокую вложенность задолго до этих чисел. Можем ли мы сделать вывод, что Except
в порядке, пока задействованы только отображенные объекты, а в противном случае Contains
лучше?
- person Gert Arnold; 06.10.2014
Пытаться:
from p in db.Products
where !theBadCategories.Contains(p.Category)
select p;
Какой SQL-запрос вы хотите преобразовать в Linq-запрос?
У меня есть следующие методы расширения:
public static bool IsIn<T>(this T keyObject, params T[] collection)
{
return collection.Contains(keyObject);
}
public static bool IsIn<T>(this T keyObject, IEnumerable<T> collection)
{
return collection.Contains(keyObject);
}
public static bool IsNotIn<T>(this T keyObject, params T[] collection)
{
return keyObject.IsIn(collection) == false;
}
public static bool IsNotIn<T>(this T keyObject, IEnumerable<T> collection)
{
return keyObject.IsIn(collection) == false;
}
Использование:
var inclusionList = new List<string> { "inclusion1", "inclusion2" };
var query = myEntities.MyEntity
.Select(e => e.Name)
.Where(e => e.IsIn(inclusionList));
var exceptionList = new List<string> { "exception1", "exception2" };
var query = myEntities.MyEntity
.Select(e => e.Name)
.Where(e => e.IsNotIn(exceptionList));
Также очень полезно при прямой передаче значений:
var query = myEntities.MyEntity
.Select(e => e.Name)
.Where(e => e.IsIn("inclusion1", "inclusion2"));
var query = myEntities.MyEntity
.Select(e => e.Name)
.Where(e => e.IsNotIn("exception1", "exception2"));
Я взял список и использовал,
!MyList.Contains(table.columb.tostring())
Примечание. Убедитесь, что вы используете List, а не Ilist.
Я создал его более похожим на SQL, думаю, это легче понять
var list = (from a in listA.AsEnumerable()
join b in listB.AsEnumerable() on a.id equals b.id into ab
from c in ab.DefaultIfEmpty()
where c != null
select new { id = c.id, name = c.nome }).ToList();