LINQ Join Where Clause

Я борюсь с предложением join/where с довольно простым выражением select sql.

Я пытаюсь получить список информации о продуктах из tb1 с условием, расположенным в tbl2, но к этому нужно добавить три разных столбца.

поэтому SQL будет выглядеть примерно так:

SELECT     tb1.*
FROM         tb2 INNER JOIN
                      tb1 ON tb2.Col1 = tb1. Col1 AND tb2.Col2 = tb1. Col2 AND 
                      tb2.Col3 = tb1.Col3
WHERE     (tb2.Col1 = col1) AND (tb2.Col2 = col2) AND (tb2.Col4 = string)

ColX - это основное предложение where с строкой, которая должна быть передана как параметр; все остальные столбцы находятся в контексте.

Как реализовать несколько соединений с предложением where?

И стреляет в правильном направлении, очень ценится.

Ответы

Ответ 1

Чтобы присоединиться к нескольким полям в LINQ, вам необходимо создать новый анонимный тип, содержащий столбцы, которые вы хотите сравнить, а затем использовать этот анонимный тип в соединении:

var results = from t1 in context.tb1
              join t2 in context.tb2
              on new { t1.Col1, t1.Col2, t1.Col3 } equals
                  new { t2.Col1, t2.Col2, t2.Col3 }
              where t2.Col1 == col1 && t2.Col2 == col2 && t2.Col4 == someString
              select t1;

И вот эквивалентный синтаксис лямбда:

var results = context.tb1.Join(
                  context.tb2,
                  t1 => new { t1.Col1, t1.Col2, t1.Col3 },
                  t2 => new { t2.Col1, t2.Col2, t2.Col3 },
                  (t1, t2) => new { t1, t2 })
              .Where(o => o.t2.Col1 == col1 
                  && o.t2.Col2 == col2
                  && o.t2.Col4 == someString)
              .Select(o => o.t1);

Как вы можете видеть, в случае объединений синтаксис запроса обычно производит более легкое для чтения утверждение.

Ответ 2

Вы также можете включить предложение WHERE в синтаксис lamda в ссылку на таблицу, в которую вы входите.

        var query = from pt in dc.ProjectTasks
                    join ttab in dc.TimeTaskAssigns on pt.Id equals ttab.ProjectTaskId
                    join ttb2 in dc.CMS_TAT_TIMEs.Where(a => a.WIP_STATUS == 'B') on ttab.CmsTimeUno equals ttb2.TIME_UNO
                    select pt;

Теперь кажется очевидным, не так ли? Мне потребовалось много времени, чтобы найти это решение.