web-dev-qa-db-fra.com

LINQ Join Where Clause

Je me bats avec une clause join/where avec ce qui est une instruction SQL plutôt simple.

J'essaie de récupérer une liste d'informations sur les produits de tb1 avec la condition where située dans tbl2, mais cela doit être joint par trois colonnes différentes.

de sorte que le SQL ressemblerait à quelque chose comme:

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 est la principale clause where avec la chaîne à passer en paramètre; toutes les autres colonnes se trouvent dans les contextes.

Comment implémentez-vous plusieurs jointures avec une clause where?

Et pousse dans la bonne direction, très appréciée.

22
Ricardo Deano

Pour joindre sur plusieurs champs dans LINQ, vous devez créer un nouveau type anonyme contenant les colonnes que vous souhaitez comparer, puis utiliser ce type anonyme dans la jointure:

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;

Et voici la syntaxe Lambda équivalente:

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);

Comme vous pouvez le voir, dans le cas des jointures, la syntaxe de requête produit généralement une instruction plus facile à lire.

53
Justin Niessner

Vous pouvez également inclure la clause WHERE dans la syntaxe lambda dans la référence à la table sur laquelle vous vous joignez.

        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;

Cela semble évident maintenant, n'est-ce pas? Il m'a fallu beaucoup de temps pour trouver cette solution.

9
Mark Williams