2015-10-28 2 views
1

Я хотел бы написать следующие SQL-запросы в запросы Linq To Entity.Несколько соединений с Linq для Entity

SELECT * 
FROM Table1 
LEFT JOIN Table2 ON Table2.IdTable1 = Table1.Id 
INNER JOIN Table3 ON Table3.IdTable2 = Table2.Id 

SELECT * 
FROM Table1 
LEFT JOIN Table2 ON Table2.IdTable1 = Table1.Id 
LEFT JOIN Table3 ON Table3.IdTable2 = Table2.Id 
WHERE Table3.Id IS NULL 

Для первого, я работаю над этим: вар запроса = RepoTable1.AsQueryable(); [некоторые запросы = query.Where (...)

query = query 
    .Join(RepoTable2.AsQueryable(), e => e.IdTable1, i => i.Id, (i, e) => i) 
    .GroupJoin(RepoTable3.AsQueryable(), c => c.IdTable2, eq => eq.Id, (eq, c) => eq); 

Существует что-то я не понимаю, о регистрации. На самом деле, «eq => eq.Id» должен иметь тип «Таблица2», но это «Таблица1». Если я изменяю "(i, e) => i" to "(i, e) => e", я получаю ошибку компиляции, потому что "запрос" ожидает типа "Table1".

А для второго запроса, я не знаю, как добавить «Где()» на Join (на самом деле, я в основном застрял с первым)

Спасибо заранее! Скажите, пожалуйста, если это недостаточно ясно!

Окончательный ответ:

query = (from t1 in query 
join t2 in RepoTable2.AsQueryable() on t1.Id equals t2.IdTable1 into joint1t2 
from t2 in joint1t2.DefaultIfEmpty() // DefaultIfEmpty is used for left joins 
join t3 in RepoTable3.AsQueryable() on t2.Id equals t3.IdT 
select t1); 

и для второго запроса:

query = (from t1 in query 
join t2 in RepoTable2.AsQueryable() on t1.Id equals t2.IdTable1 into joint1t2 
from t2 in joint1t2.DefaultIfEmpty() // DefaultIfEmpty is used for left joins 
join t3 in RepoTable3.AsQueryable() on t2.Id equals t3.IdTable2 into joint2t3 
from t3 in joint2t3.DefaultIfEmpty() // DefaultIfEmpty is used for left joins 
where t3.Id== null 
select t1); 
+0

Я ненавижу левые соединения в LINQ, но я могу объяснить некоторые из них для вас. '(i, e)' должно быть, скорее всего, '(e, i)' на основе вашего предыдущего использования 'e', чтобы ссылаться на Таблицу 1, и' i' ссылаться на Таблицу 2. Далее следует, что вы не должны прерывать запрос, потому что окончательный возврат не является (не должен?) Быть просто записями, которые содержатся в таблице1, или вам нужно поместить результат второй части запроса в другая переменная. Думая об этом по-другому, 'ReportTable1.AsQueryable()' возвращает 'IQueryable ', и ваш окончательный запрос не должен возвращать это. –

+0

Ваш последний запрос должен возвращать некоторый IQueryable анонимного типа, который включает все поля из таблицы1, table2 и table3. –

+0

Я склоняюсь к тому, чтобы найти синтаксис метода для объединений в Linq, чтобы быть одной из худших вещей для записи. Вы пытались написать его в синтаксисе запроса? Полученный синтаксис запроса очень похож на SQL, который у вас уже есть. –

ответ

0

Я бы рекомендовал использовать синтаксис запроса (Если вы не можете использовать навигационные свойства)

Ваш первый запрос выглядел бы очень похоже с использованием этого синтаксиса

var query = 
    from t1 in RepoTable1.AsQueryable() 
    join t2 in RepoTable2.AsQueryable() on t1.Id equals t2.Id into t2g 
    from t2 in t2g.DefaultIfEmpty() //DefaultIfEmpty is used for left joins 
    join t3 in RepoTable3.AsQueryable() on t2.Id equals t3.Id 
    select new 
    { 
    t1, t2, t3 
    }; 
+0

Это замечательно, спасибо. Я использовал свой переменный «запрос» типа IQueryable вместо RepoTable1.AsQueryable(). Но теперь мне не нужно «слить» мой запрос Linq-to-Entity с новым запросом Linq-to-SQL. Попытка сделать это, но если у вас есть какие-то советы ... – Grimness

Смежные вопросы