LINQ & EF Core Building Query для «не в» - PullRequest
0 голосов
/ 09 ноября 2019

Допустим, эти 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?

...