Допустим, эти 2 упрощенные таблицы:
TableOne
public int OneId { get; set; }
public ICollection<TableTwo> TableTwo { get; set; }
со значениями
OneId
1
2
3
TableTwo
public int OneId { get; set; }
public string Color {get; set; }
public int AnotherId {get; set; }
public TableOne TableOne { get; set; }
со значениями
OneId | Color | AnotherId
1 | Blue | 9
1 | Green | 1
2 | Blue | 1
То, что я хотел бы получить, это все TableOne
, которые не помечены как Blue
и AnotherId != 9
.
Я могу сделать это за 2 шага бедняка. Сначала получите противоположность того, что я хочу:
var firstStep = await TableOne
.AsNoTracking()
.Where(o => o.TableTwo.Any(t => t.Color == "Blue" && t.AnotherId == '9'))
.Select(o => o.OneId)
.ToListAsync();
Что дает мне List<int>
, что я могу сделать это:
var secondStep = from a in TableOne
where !firstStep.Contains(a.OneId)
select a;
var finalResult = await secondStep.ToListAsync();
И это правильно вернет то, что я ищу:
OneId
2
3
1
- единственный, который не соответствует критериям, поскольку он единственный, помеченный Blue
и 9
.
Что я не делаюПримером такого подхода является SQL, который генерирует .Contains
.
SELECT `a`.`OneId`
FROM `TableOne` AS `a`
WHERE `a`.`OneId` NOT IN (1)
Часть NOT IN
может потенциально иметь тысячи значений, и результирующий запрос не параметризован, что делает ЦП несчастным.
Как я могу превратить это в NOT EXISTS
вместо NOT IN
?