it-swarm.com.de

LINQ to SQL: Mehrere Joins auf mehreren Spalten. Ist das möglich?

Gegeben:

Eine Tabelle mit dem Namen TABLE_1 mit den folgenden Spalten:

  • ID
  • ColumnA
  • ColumnB
  • ColumnC

Ich habe eine SQL-Abfrage, bei der TABLE_1 sich zweimal basierend auf ColumnA, ColumnB, ColumnC auf sich selbst verbindet. Die Abfrage könnte ungefähr so ​​aussehen:

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.

Problem:

Ich muss diese Abfrage in LINQ umschreiben. Ich habe versucht, einen Versuch zu unternehmen:

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 :(

Wie schreibe ich meine Abfrage in LINQ? Was mache ich falsch?

112
DJTripleThreat

Das Zusammenfügen mehrerer Spalten in Linq zu SQL unterscheidet sich ein wenig.

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 }
    ...

Sie müssen anonyme Typen nutzen und einen Typ für die mehreren Spalten erstellen, mit denen Sie vergleichen möchten.

Dies erscheint zunächst verwirrend, aber wenn Sie erst einmal mit der Zusammensetzung von SQL aus den Ausdrücken vertraut gemacht werden, wird es viel sinnvoller. Unter den Deckblättern wird dann die Art des gewünschten Join generiert.

EDITHinzufügen eines Beispiels für den zweiten Join basierend auf Kommentar.

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 }
    ...
206

Title_Authors ist ein Suchvorgang, bei dem zwei Projektergebnisse zusammengeführt werden und die Verkettung fortgesetzt wird

        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;
        }
9
BionicCyborg

In LINQ2SQL müssen Sie selten explizit bei der Verwendung von inneren Joins beitreten.

Wenn Sie über korrekte Fremdschlüsselbeziehungen in Ihrer Datenbank verfügen, erhalten Sie automatisch eine Beziehung im LINQ-Designer (andernfalls können Sie eine Beziehung manuell im Designer erstellen. In der Datenbank sollten Sie jedoch richtige Beziehungen haben)

parent-child relation

Dann können Sie einfach auf verwandte Tabellen mit der "Punktnotation" zugreifen.

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

generiert die Abfrage

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

Meiner Meinung nach ist dies viel lesbarer und Sie können sich auf Ihre speziellen Bedingungen konzentrieren und nicht auf die eigentliche Mechanik des Joins.

Bearbeiten
Dies gilt natürlich nur, wenn Sie sich unserem Datenbankmodell anschließen möchten. Wenn Sie "außerhalb des Modells" beitreten möchten, müssen Sie auf manuelle Verknüpfungen wie in answer from Quintin Robinson zurückgreifen.

9
Albin Sunnanbo

Sie können auch verwenden:

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 }
8
Baqer Naqvi

Ich möchte ein anderes Beispiel geben, in dem mehrere (3) Joins verwendet werden.

 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
                  };
3
user3477428

Sie können auch beitreten, wenn die Anzahl der Spalten in beiden Tabellen nicht identisch ist und statische Werte der Tabellenspalte zugeordnet werden können

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}
0
Ankit Arya