Question

Vu:

Une table nommée TABLE_1 avec les colonnes suivantes:

  • ID
  • ColumnA
  • ColumnB
  • ColumnC

J'ai requête SQL où TABLE_1 se joint sur elle-même basée deux fois au large de ColumnA, ColumnB, ColumnC. La requête pourrait ressembler à ceci:

Select t1.ID, t2.ID, t3.ID
  From TABLE_1 t1
  Left Join TABLE_1 t2 On
       t1.ColumnA = t2.ColumnA
   And t1.ColumnB = t2.ColumnB
   And t1.ColumnC = t2.ColumnC
  Left Join TABLE_1 t3 On
       t2.ColumnA = t3.ColumnA
   And t2.ColumnB = t3.ColumnB
   And t2.ColumnC = t3.ColumnC
... and query continues on etc.

Problème:

J'ai besoin que la requête est réécrite dans LINQ. Je l'ai essayé de prendre un coup de poignard à elle:

var query =
    from t1 in myTABLE1List // List<TABLE_1>
    join t2 in myTABLE1List
      on t1.ColumnA equals t2.ColumnA
      && t1.ColumnB equals t2.ColumnA
    // ... and at this point intellisense is making it very obvious
    // I am doing something wrong :(

Comment puis-je écrire ma requête dans LINQ? Qu'est-ce que je fais mal?

Était-ce utile?

La solution

Rejoindre sur plusieurs colonnes dans LINQ to SQL est un peu différent.

var query =
    from t1 in myTABLE1List // List<TABLE_1>
    join t2 in myTABLE1List
      on new { t1.ColumnA, t1.ColumnB } equals new { t2.ColumnA, t2.ColumnB }
    ...

Vous devez profiter des types anonymes et de composer un type pour les multiples colonnes que vous souhaitez comparer contre.

Cela semble déroutant au début, mais une fois que vous vous familiariser avec la façon dont le SQL est composé à partir des expressions qu'il fera beaucoup plus de sens, sous les couvertures cela va générer le type de vous joindre recherchez.

EDIT Ajout exemple pour la deuxième jointure basée sur le commentaire.

var query =
    from t1 in myTABLE1List // List<TABLE_1>
    join t2 in myTABLE1List
      on new { A = t1.ColumnA, B = t1.ColumnB } equals new { A = t2.ColumnA, B = t2.ColumnB }
    join t3 in myTABLE1List
      on new { A = t2.ColumnA, B =  t2.ColumnB } equals new { A = t3.ColumnA, B = t3.ColumnB }
    ...

Autres conseils

Title_Authors est un regard deux choses se joindre à un des résultats du projet de temps et continuer enchaînant

        DataClasses1DataContext db = new DataClasses1DataContext();
        var queryresults = from a in db.Authors                                          
                    join ba in db.Title_Authors                           
                    on a.Au_ID equals ba.Au_ID into idAuthor
                    from c in idAuthor
                    join t in db.Titles  
                    on c.ISBN equals t.ISBN 
                    select new { Author = a.Author1,Title= t.Title1 };

        foreach (var item in queryresults)
        {
            MessageBox.Show(item.Author);
            MessageBox.Show(item.Title);
            return;
        }

Dans LINQ2SQL ont rarement besoin de se joindre explicitement lors de l'utilisation des jointures internes.

Si vous avez des relations appropriées de clé étrangère dans votre base de données, vous obtiendrez automatiquement une relation dans le concepteur LINQ (sinon vous pouvez créer une relation manuellement dans le concepteur, bien que vous devriez vraiment avoir des relations appropriées dans votre base de données)

relation parent-enfant

Ensuite, vous pouvez simplement les tables liées à l'accès à la "dot-notation"

var q = from child in context.Childs
        where child.Parent.col2 == 4
        select new
        {
            childCol1 = child.col1,
            parentCol1 = child.Parent.col1,
        };

va générer la requête

SELECT [t0].[col1] AS [childCol1], [t1].[col1] AS [parentCol1]
FROM [dbo].[Child] AS [t0]
INNER JOIN [dbo].[Parent] AS [t1] ON ([t1].[col1] = [t0].[col1]) AND ([t1].[col2] = [t0].[col2])
WHERE [t1].[col2] = @p0
-- @p0: Input Int (Size = -1; Prec = 0; Scale = 0) [4]
-- Context: SqlProvider(Sql2008) Model: AttributedMetaModel Build: 4.0.30319.1

À mon avis, c'est beaucoup plus lisible et permet de vous concentrer sur vos conditions particulières et non les mécanismes réels de la jointure.

Modifier Ceci est bien sûr applicable uniquement lorsque vous souhaitez vous joindre à la ligne avec notre modèle de base de données. Si vous souhaitez rejoindre « en dehors du modèle », vous devez recourir au manuel comme dans le joint réponse de Quintin Robinson

U peut également utiliser:

var query =
    from t1 in myTABLE1List 
    join t2 in myTABLE1List
      on new { ColA=t1.ColumnA, ColB=t1.ColumnB } equals new { ColA=t2.ColumnA, ColB=t2.ColumnB }
    join t3 in myTABLE1List
      on new {ColC=t2.ColumnA, ColD=t2.ColumnB } equals new { ColC=t3.ColumnA, ColD=t3.ColumnB }

je voudrais donner un autre exemple dans lequel de multiples (3) rejoint sont utilisés.

 DataClasses1DataContext ctx = new DataClasses1DataContext();

        var Owners = ctx.OwnerMasters;
        var Category = ctx.CategoryMasters;
        var Status = ctx.StatusMasters;
        var Tasks = ctx.TaskMasters;

        var xyz = from t in Tasks
                  join c in Category
                  on t.TaskCategory equals c.CategoryID
                  join s in Status
                  on t.TaskStatus equals s.StatusID
                  join o in Owners
                  on t.TaskOwner equals o.OwnerID
                  select new
                  {
                      t.TaskID,
                      t.TaskShortDescription,
                      c.CategoryName,
                      s.StatusName,
                      o.OwnerName
                  };

Vous pouvez également joindre si le nombre de colonnes ne sont pas identiques dans les deux tables et peut mapper valeur statique à la colonne de table

from t1 in Table1 
join t2 in Table2 
on new {X = t1.Column1, Y = 0 } on new {X = t2.Column1, Y = t2.Column2 }
select new {t1, t2}

À mon avis, c'est la façon la plus simple de joindre deux tables avec plusieurs champs:

from a in Table1 join b in Table2    
       on (a.Field1.ToString() + "&" + a.Field2.ToString())     
       equals  (b.Field1.ToString() + "&" + b.Field2.ToString())  
     select a

Vous pouvez écrire votre requête comme ceci.

var query = from t1 in myTABLE1List // List<TABLE_1>
            join t2 in myTABLE1List
               on t1.ColumnA equals t2.ColumnA
               and t1.ColumnB equals t2.ColumnA

Si vous voulez comparer votre colonne avec plusieurs colonnes.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top