11
votes

Aider à comprendre l'énumérable.join Méthode

hier i Posté cette question concernant l'utilisation de Lambdas à l'intérieur d'une méthode de jointure () pour vérifier si 2 conditions existent sur 2 entités. J'ai reçu une réponse sur la question qui a parfaitement fonctionné. Je pensais après avoir lu l'article MSDN sur la méthode énoin (), je comprendrais exactement ce qui se passait, mais je ne le fais pas. Quelqu'un pourrait-il m'aider à comprendre ce qui se passe dans le code ci-dessous (la méthode de jointure () spécifiquement)? Merci d'avance.

if (db.TableA.Where( a => a.UserID == currentUser )
      .Join( db.TableB.Where( b => b.MyField == someValue ),
             o => o.someFieldID,
             i => i.someFieldID,
             (o,i) => o )
      .Any()) 
{
    //...
}


0 commentaires

4 Réponses :


2
votes

Cette requête dit rejoindre Tablea code> à Tableb code> où Tablea.SomeField == tablef.SomeField == tableb.SomeField = et sélectionnez les résultats du tavel et de la vue si Il y a des résultats du tout

en termes de SQL y penser comme ceci, même si ce n'est pas Linq-to-SQL ... Si vous connaissez SQL peut-être que cela a plus de sens: P>

Select Count(*)
From TableA a
     Join TableB b
       On a.someFieldID = b.someFieldID


0 commentaires

23
votes

La syntaxe de jointure est xxx

de sorte que vous avez deux tables. Vous avez une clé qui est commune aux deux tables. Vous fournissez deux extracteurs clés qui savent comment obtenir la clé de chaque ligne de la table.

La logique de jointure identifie des paires de lignes, une de chaque table, qui ont la même clé.

chacune de ces lignes est ensuite exécutée dans le sélecteur pour projeter le résultat.

Est-ce que cela répond à votre question?


4 commentaires

Presque. Je comprends le premier paramètre étant une entité (d'une table correspondant à ces conditions), mais je suis curieux de savoir comment les 3 autres paramètres fonctionnent. Ce qui se passe exactement à ce stade: O => O.SomeFiide, I => I.SomeFiide, (O, I) => O


@LUSH - Le deuxième paramètre indique le champ de la table d'origine que vous correspondez sur ( Tablea.SomeField ), le troisième paramètre indique quel champ sur la table jointe que vous correspondez à ( Tableb.SomeField ). Le dernier paramètre dit à partir de ce nouvel ensemble de tables, ce que vous sélectionnez ... Dans ce cas, tout est de Tablea . Dans votre code, vous pouvez remplacer o avec A i avec b , cela peut le rendre plus clair voir.


Mais comment le code "O => O.SomeField" est-il traduit vers "Tablea.Somefieldid"? Qu'est-ce qui se passe sous la capuche?


J'ai mis à jour ma réponse pour couvrir la syntaxe O => O.Somefield.



6
votes

Explication de la jointure.

B = type d'objet de la première table o = type d'objet de la première table i = type d'objet de la deuxième table

  1. db.tableb.herwhere (b => b.myfield == quelqueévalue) Il s'agit du type d'élément de la deuxième table
  2. o => O.SomeField la clé de la première table
  3. i => i.somefield la clé de la deuxième table (qui correspondra à la clé de la première table)
  4. (o, i) => o l'objet à revenir, dans ce cas, le type d'objet de la première table.

0 commentaires

4
votes

Eric et Nick ont ​​à la fois fourni de bonnes réponses.

Vous pouvez également écrire l'expression de requête LINQ à l'aide de la syntaxe de requête (syntaxe par rapport à la méthode que vous utilisez dans votre exemple): p>

if (db.TableA.Where( delegate(EntityType a) { return a.UserID == currentUser; } ) 
  .Join( db.TableB.Where( delegate(EntityType b) { return b.MyField == someValue; } ), 
         delegate(EntityType o) { return o.somefieldId); },
         delegate(EntityType i) { return i.someFieldId); },
         delegate(EntityType o, EntityType i) { return o; }) 
  .Any())  


4 commentaires

Oui, j'avais effectivement écrit de cette façon, puis après avoir réalisé qu'il pouvait être accompli à l'aide de la méthode de jointure à l'aide de Lambdas, je pensais que je me mettais au défi. Je crois toujours que cette façon d'être plus claire et de mettre en œuvre probablement la solution de cette façon, mais je veux bien comprendre l'autre technique d'abord.


Dans votre exemple mis à jour, le deuxième délégué ne devrait-il pas être délégué (EntityType O) (EntityType I)?


Oui, merci Metro Schtroumpf (je ne peux pas croire que ces deux mots apparaissent un après un autre lol).


Parfait, c'est exactement ce que je cherchais, étant donné ma compréhension des types implicites et que je connais peu les méthodes anonymes et les expressions de Lambda jusqu'à présent. J'apprécie particulièrement votre exemple de code. Merci.