50 votes

LINQ Join avec plusieurs clauses From

Lorsque j'écris des requêtes LINQ en C#, je sais que je peux effectuer une jointure en utilisant la fonction join mot-clé. Mais que fait ce qui suit ?

from c in Companies
from e in c.Employees
select e;

Un livre LINQ que j'ai dit qu'il s'agit d'un type de jointure, mais pas d'une jointure proprement dite (qui utilise la balise join mot-clé). Alors, quel type de jointure est-ce exactement ?

50voto

Nathan Tregillus Points 1450

Les instructions "from" multiples sont considérées comme des instructions linq composées. Elles sont comme des instructions foreach imbriquées. La page msdn donne un excellent exemple aquí

var scoreQuery = from student in students
                 from score in student.Scores
                 where score > 90
                 select new { Last = student.LastName, score };

cette déclaration pourrait être réécrite comme suit :

SomeDupCollection<string, decimal> nameScore = new SomeDupCollection<string, float>();
foreach(Student curStudent in students)
{
   foreach(Score curScore in curStudent.scores)
   {
      if (curScore > 90)
      {
         nameScore.Add(curStudent.LastName, curScore);
      }
   }
}

29voto

Ken Pespisa Points 14935

Cela sera traduit en un SelectMany() appel. Il s'agit essentiellement d'une jonction croisée.

Jon Skeet en parle sur son blog, dans le cadre de l'opération Série Edulinq . (Faites défiler jusqu'à Clauses "de" secondaires .)

21voto

StriplingWarrior Points 56276

Le code que vous avez indiqué :

from c in company
from e in c.Employees
select e;

... produira une liste de tous les employés de toutes les entreprises de l'UE. company variable. Si un employé travaille pour deux entreprises, il sera inclus deux fois dans la liste.

La seule "jointure" qui pourrait se produire ici est lorsque vous dites c.Employees . Dans un fournisseur basé sur SQL, cela se traduirait par une jointure interne à partir de la base de données de l'utilisateur. Company à la table Employee table.

Cependant, le double- from est souvent utilisée pour effectuer des "jointures" manuellement, comme ceci :

from c in companies
from e in employees
where c.CompanyId == e.CompanyId
select e;

Cela aurait un effet similaire à celui du code que vous avez posté, avec de potentielles différences subtiles en fonction de ce que l'option employees contient. Ceci serait également équivalent à ce qui suit join :

from c in companies
join e in employees
   on c.CompanyId equals e.CompanyId
select e;

Si vous vouliez un produit cartésien, cependant, vous pourriez simplement supprimer l'élément where clause. (Pour que cela vaille la peine, il faudrait probablement modifier la clause select légèrement, aussi, cependant).

from c in companies
from e in employees
select new {c, e};

Cette dernière requête vous donnera toutes les combinaisons possibles d'entreprises et d'employés.

-1voto

Trent Points 884

Tous les objets du premier ensemble seront joints à tous les objets du deuxième ensemble. Par exemple, le test suivant passera...

    [TestMethod()]
    public void TestJoin()
    {
        var list1 = new List<Object1>();
        var list2 = new List<Object2>();

        list1.Add(new Object1 { Prop1 = 1, Prop2 = "2" });
        list1.Add(new Object1 { Prop1 = 4, Prop2 = "2av" });
        list1.Add(new Object1 { Prop1 = 5, Prop2 = "2gks" });

        list2.Add(new Object2 { Prop1 = 3, Prop2 = "wq" });
        list2.Add(new Object2 { Prop1 = 9, Prop2 = "sdf" });

        var list = (from l1 in list1
                    from l2 in list2
                    select l1).ToList();

        Assert.AreEqual(6, list.Count);

    }

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X