web-dev-qa-db-fra.com

LINQ Left Join Et Right Join

J'ai besoin d'aide,

J'ai deux dataTable appelés A et B, j'ai besoin de toutes les lignes de A et de la ligne correspondante de 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

J'ai besoin de mettre:

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

Les exemples de données et de sortie que vous avez fournis ne démontrent pas une jointure gauche. Si c'était une jointure à gauche, votre sortie ressemblerait à ceci (notez comment nous avons 3 résultats pour l'utilisateur 1, c'est-à-dire une fois pour chaque enregistrement de croissance que l'utilisateur 1 a):

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  |

En supposant que vous ayez toujours besoin d'une jointure gauche; voici comment vous faites une jointure à gauche dans 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
              };

Si vous voulez faire une jointure à droite, échangez simplement les tables que vous avez sélectionnées, comme suit:

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

La partie importante du code est l'instruction into, suivie de DefaultIfEmpty . Cela indique à Linq que nous voulons avoir la valeur par défaut (c'est-à-dire null) s'il n'y a pas de résultat correspondant dans l'autre table.

33
Doctor Jones

Le Docteur Jones a montré la jointure externe gauche, mais la réponse correcte serait légèrement différente, car dans la question initiale, deux tables liées sur un champ d'âge afin d'obtenir le résultat exactement comme il convient, le code suivant doit être utilisé.

....
//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; }
    }
5
Vitaliy Markitanov

Un moyen facile consiste à utiliser le mot clé Let. Cela fonctionne pour moi.

from AItem in Db.A
Let BItem = Db.B.Where(x => x.id == AItem.id ).FirstOrDefault() 
Where SomeCondition
Select new YourViewModel
{
    X1 = AItem.a,
    X2 = AItem.b,
    X3 = BItem.c
}

Ceci est une simulation de Left Join. Si chaque élément de la table B ne correspond pas à l'élément A, BItem renvoie null

0
mahdi moghimi