LINQ to Entity: условия множественного соединения
Существует множество сообщений о LINQ и нескольких соединениях. Я, однако, не нашел решения для присоединения, которое я хотел бы сделать.
Эквивалент SQL будет примерно таким:
SELECT * FROM table1 a
LEFT JOIN table2 b ON a.col1 = b.key1 AND
a.col2 = b.key2 AND
b.from_date <= now() AND
b.deleted = 0;
Здесь один из многочисленных запросов linq, которые я пытался
var query = (from x in context.table1
join y in context.table2 on new {x.col1, x.col2} equals {b.key1, b.key2}
into result
from result......
Как добавить дополнительные условия даты и удалить флаг? Если я использую условия. В этом случае это рассматривается как внутреннее соединение, а не левое соединение.
Ответы
Ответ 1
Другой способ может быть подобен
var query = (from x in context.table1
join y in context.table2 on
new {
Key1 = x.col1,
Key2 = x.col2
Key3 = true,
Key4 = true
}
equals
new {
Key1 = y.key1,
Key2 = y.key2,
Key3 = y.from_date< DateTime.Now,
Key4 = !y.deleted
}
into result
from r in result.DefaultIfEmpty()
select new {x.Something, r.Something}
Ответ 2
LINQ поддерживает синтаксис соединения и более старый синтаксис ANSI-82 WHERE. Используя позже, вы можете делать то, с чем вы смотрите
var nowTime = DateTime.Now;
var query = from a in context.table1
from b in context.table2
where a.col1 == b.key1
&& a.col2 == b.key2
&& b.from_date < nowTime
&& b.deleted == false
select ???;
Кроме того, вы можете использовать гибрид, где и присоединиться. (Реализуйте, что порядок в запросе LINQ не должен имитировать то, что вы бы сделали в SQL, и порядок более гибкий.)
var nowTime = DateTime.Now;
var query = from b in context.table2
where b.from_date < nowTime
&& b.deleted == false
join a on new {b.key1, b.key2} equals new {a.col1, a.col2}
select ???;
Ответ 3
Не могли бы вы просто отфильтровать первый результирующий набор со вторым запросом?
var query = (from x in context.table1
join y in context.table2 on new {x.col1, x.col2} equals {b.key1, b.key2}
into result
query = from x in query
where ...
Будет ли это работать?
Ответ 4
У меня возникла проблема с именем свойств в анонимном объекте:
var subscriptions = context.EmailSubscription.Join(context.EmailQueue,
es => new { es.Id, 9 },
eq => new { eq.EmailSubscriptionId, eq.EmailTemplateId },
(es, eq) => new { es.Id, eq.Id }
).ToList();
Компилятор был недоволен, поэтому выше ответа помогает мне разобраться, что случилось, и вот мое рабочее решение. Мне понадобилось время, чтобы найти тупую ошибку :):
var subscriptions = context.EmailSubscription.Join(context.EmailQueue,
es => new { EmailSubscriptionId = es.Id, EmailTemplateId = 9 },
eq => new { eq.EmailSubscriptionId, eq.EmailTemplateId },
(es, eq) => new { es.Id, eq.Id }
).ToList();