Я пытаюсь реализовать запрос в LINQ, который использует левое внешнее соединение с несколькими условиями в предложении ON.
Я буду использовать пример следующих двух таблиц: Project (ProjectID, ProjectName) и Task (TaskID, ProjectID, TaskName, Completed). Я хочу видеть полный список всех проектов с соответствующими задачами, но только те задачи, которые выполнены.
Я не могу использовать фильтр, Completed == true
потому что он отфильтрует все проекты, у которых нет завершенных задач. Вместо этого я хочу добавить Completed == true
в предложение ON соединения, чтобы отображался полный список проектов, но отображались только выполненные задачи. В проектах без завершенных задач будет отображаться одна строка с нулевым значением для задачи.
Вот основа запроса.
from t1 in Projects
join t2 in Tasks
on new { t1.ProjectID} equals new { t2.ProjectID } into j1
from j2 in j1.DefaultIfEmpty()
select new { t1.ProjectName, t2.TaskName }
Как добавить && t2.Completed == true
в предложение on?
Кажется, я не могу найти документацию LINQ о том, как это сделать.
Ответы:
Вам просто нужно назвать анонимное свойство одинаковым с обеих сторон.
on new { t1.ProjectID, SecondProperty = true } equals new { t2.ProjectID, SecondProperty = t2.Completed } into j1
Основываясь на комментариях @svick, вот еще одна реализация, которая может иметь больше смысла:
from t1 in Projects from t2 in Tasks.Where(x => t1.ProjectID == x.ProjectID && x.Completed == true) .DefaultIfEmpty() select new { t1.ProjectName, t2.TaskName }
источник
and
, а не одно равенство какого-то «странного» объекта. И чтобы доказать мою точку зрения, ваш код неверен. Чтобы он работал, у вас должны бытьtrue
слева иt2.Complete
справа.AND SecondProperty IN (123, 456)
. Я перейду к этой задаче и буду очень признателен за любую помощь, которую вы могли бы оказать.Вот вам:
from b in _dbContext.Burden join bl in _dbContext.BurdenLookups on new { Organization_Type = b.Organization_Type_ID, Cost_Type = b.Cost_Type_ID } equals new { Organization_Type = bl.Organization_Type_ID, Cost_Type = bl.Cost_Type_ID }
источник
Вы не можете этого сделать. Предложение
join
(иJoin()
метод расширения) поддерживает только эквивалентные соединения. Это также причина, почему он использует,equals
а не==
. И даже если бы вы могли сделать что-то подобное, это не сработало бы, потому чтоjoin
это внутреннее соединение, а не внешнее соединение.источник
Это отлично работает для 2 таблиц. У меня есть 3 таблицы, и в статье нужно связать 2 условия из 3 таблиц. Мой код:
из p в _dbContext.Products присоединяются к pv в _dbContext.ProductVariants на p.ProduktId равны pv.ProduktId join jpr в leftJoinQuery на новом {VariantId = pv.Vid, ProductId = p.ProduktId} равняется new {VariantPrices.VariantId = jpr.Id. ProductId = jpr.Prices.ProduktID} в lj
Но на этом этапе отображается ошибка: присоединиться к pv в _dbContext.ProductVariants на p.ProduktId равно pv.ProduktId
Ошибка: неверный тип одного из выражений в предложении соединения. Не удалось определить тип при вызове GroupJoin.
источник