2010-12-21 23 views
20

ich eine Hilfe benötigen,LINQ LEFT JOIN und Join Rechts

Ich habe zwei Datatable genannt A und B, ich brauche alle Zeilen aus A und passende Reihe von B

Ex:

A:           B: 

User | age| Data       ID | age|Growth         
1 |2 |43.5        1 |2 |46.5 
2 |3 |44.5        1 |5 |49.5 
3 |4 |45.6        1 |6 |48.5 

ich brauche Out Put:

User | age| Data |Growth 
------------------------       
1 |2 |43.5 |46.5       
2 |3 |44.5 |       
3 |4 |45.6 | 

Antwort

26

Die Beispieldaten und Ausgabe Sie zur Verfügung gestellt haben nicht zeigen keine LEFT JOIN. Wenn es eine linke war beitreten Ihre Ausgabe würde wie folgt aussehen (beachten Sie, wie wir haben 3 Ergebnisse für Benutzer 1, dh einmal für jedes Wachstum Rekord, dass Benutzer 1 hat):

User | age| Data |Growth 
------------------------       
1 |2 |43.5 |46.5       
1 |2 |43.5 |49.5  
1 |2 |43.5 |48.5  
2 |3 |44.5 |       
3 |4 |45.6 | 

Unter der Annahme, dass Sie benötigen noch eine LEFT JOIN ; hier ist, wie Sie links trete in Linq:

var results = from data in userData 
       join growth in userGrowth 
       on data.User equals growth.User into joined 
       from j in joined.DefaultIfEmpty() 
       select new 
       { 
        UserData = data, 
        UserGrowth = j 
       }; 

Wenn Sie ein Recht machen wollen join, nur die Tabellen tauschen, die Sie unter den über sind die Auswahl, etwa so:

var results = from growth in userGrowth 
       join data in userData 
       on growth.User equals data.User into joined 
       from j in joined.DefaultIfEmpty() 
       select new 
       { 
        UserData = j, 
        UserGrowth = growth 
       }; 

die wichtige Teil des Codes ist die Anweisung into, gefolgt von DefaultIfEmpty. Dies teilt Linq mit, dass wir den Standardwert (d. H. Null) haben möchten, wenn in der anderen Tabelle kein übereinstimmendes Ergebnis vorhanden ist.

4

Doktor Jones zeigte linken Outer Join, aber die richtige Antwort wäre etwas anders - weil in der ursprünglichen Frage zwei Tabellen auf Alter Feld verknüpft, so dass Ergebnis genau nach Bedarf folgenden Code zu erhalten, sollte verwendet werden.

.... 
//ctx = dataContext class - not shown here. 
var user1 = new UserData() { User = 1, Age = 2, Data = 43.5 }; 
var user2 = new UserData() { User = 2, Age = 3, Data = 44.5 }; 
var user3 = new UserData() { User = 3, Age = 4, Data = 45.6 }; 

ctx.UserData.AddRange(new List<UserData> { user1, user2, user3 }); 

var growth1 = new UserGrowth() { Id = 1, Age = 2, Growth = 46.5 }; 
var growth2 = new UserGrowth() { Id = 1, Age = 5, Growth = 49.5 }; 
var growth3 = new UserGrowth() { Id = 1, Age = 6, Growth = 48.5 }; 

ctx.UserGrowth.AddRange(new List<UserGrowth> { growth1, growth2, growth3 }); 

var query = from userData in ctx.UserData 
         join userGrowth in ctx.UserGrowth on userData.Age equals userGrowth.Age 
          into joinGroup 
         from gr in joinGroup.DefaultIfEmpty() 
         select new 
         { 
          User = userData.User, 
          age = userData.Age, 
          Data = (double?)userData.Data, 
          Growth = (double?)gr.Growth 
         }; 

Console.WriteLine("{0} | {1} | {2} | {3}", "User", "age", "Data", "Growth"); 
      foreach (var x in query) 
      { 
       Console.WriteLine("{0} | {1} | {2} | {3}", x.User, x.age, x.Data, x.Growth); 
      } 


.... with following entity classes: 

public class UserData 
    { 
     [Key] 
     public int User { get; set; } 
     public int Age { get; set; } 
     public double Data { get; set; } 
    } 

    public class UserGrowth 
    { 
     public int Id { get; set; } 
     public int Age { get; set; } 
     public double Growth { get; set; } 
    }