283 votes

Comment faire des jointures dans LINQ sur plusieurs champs en simple jointure

J'ai besoin de faire un LINQ2DataSet requête qui fait une jointure sur plus d'un domaine (comme

var result = from x in entity
join y in entity2 
       on x.field1 = y.field1 
and 
          x.field2 = y.field2

Je n'ai pas encore trouvé une solution convenable (je peux ajouter d'autres contraintes à une clause where, mais c'est loin d'être une solution appropriée, ou d'utiliser cette solution, mais cela suppose une équi-jointure).

Est-il possible dans LINQ to join sur plusieurs champs dans une seule jointure?

MODIFIER

var result = from x in entity
             join y in entity2
             on new { x.field1, x.field2 } equals new { y.field1, y.field2 }

est la solution que j'ai référencé comme dans l'hypothèse d'un équi-jointure au-dessus.

En outre MODIFIER

En réponse aux critiques que mon exemple était une équi-jointure, je dois reconnaître que, Mon exigence est actuellement pour une équi-jointure et j'ai déjà utilisé la solution que j'ai référencé ci-dessus.

Je suis, cependant, en essayant de comprendre quelles sont les possibilités et les meilleures pratiques que j'ai / devrait employer avec LINQ. Je vais avoir besoin de faire une plage de Date de requête de jointure avec une table ID bientôt, et c'était juste préjuger de la question, On dirait que j'ai à ajouter de la plage de dates dans la clause where.

Merci, comme toujours, pour toutes suggestions et commentaires

156voto

KristoferA Points 8036
var result = from x in entity
   join y in entity2 on new { x.field1, x.field2 } equals new { y.field1, y.field2 }

94voto

Jon Skeet Points 692016

La solution avec le type anonyme devrait fonctionner correctement. LINQ peut seulement représenter equijoins (avec des clauses de jointure, de toute façon), et en effet c'est ce que vous avez dit que vous vouliez exprimer toute façon, basé sur l'original de votre requête.

Si vous n'aimez pas la version avec le type anonyme, pour quelque raison, vous devez expliquer que la raison.

Si vous voulez faire autre chose que ce que vous demandiez, veuillez donner un exemple de ce que vous avez vraiment envie de faire.

EDIT: en Réponse à la modifier dans la question: oui, pour faire un "jour de la gamme" nous rejoindre, vous devez utiliser une clause where à la place. Ils sont sémantiquement équivalentes vraiment, si c'est juste une question de les optimisations disponibles. Equijoins offrir une simple optimisation (dans LINQ to Objects, qui comprend LINQ to jeux de données) par la création d'une recherche basée sur la face interne de la séquence de penser à cela comme une table de hachage de la clé à une séquence d'entrées correspondant à celle de la clé.

Que faire avec les plages de date est un peu plus difficile. Cependant, en fonction de ce que vous entendez par "date gamme rejoindre, vous pourriez être en mesure de faire quelque chose de similaire - si vous avez l'intention sur la création de "groupes" de dates (par exemple, une fois par an) telle que deux entrées qui se trouvent dans la même année (mais pas à la même date) doit correspondre, alors vous pouvez le faire simplement en utilisant le groupe comme la clé. Si c'est plus compliqué, par exemple, d'un côté de la jointure fournit une gamme, et de l'autre côté de la jointure fournit une date unique, correspondant si elle tombe à l'intérieur de cette gamme, que ce serait mieux gérée avec un where de l'alinéa (après une seconde, from clause) de l'OMI. Vous pourriez faire quelques particulièrement funky de la magie par la commande d'un côté ou de l'autre pour trouver des correspondances de manière plus efficace, mais ce serait beaucoup de travail, je ne pourrais que faire ce genre de chose après avoir vérifié si la performance est un problème.

58voto

NIXin Points 44

Juste pour compléter ceci avec une syntaxe de chaîne de méthode équivalente:

 entity.Join(entity2, x => new {x.Field1, x.Field2},
                     y => new {y.Field1, y.Field2}, (x, y) => x);
 

Alors que le dernier argument (x, y) => x est ce que vous sélectionnez (dans le cas ci-dessus, nous sélectionnons x ).

9voto

Perpetualcoder Points 7381

vous pourriez faire quelque chose comme (ci-dessous)

 var query = from p in context.T1

        join q in context.T2

        on

        new { p.Col1, p.Col2 }

        equals

         new { q.Col1, q.Col2 }

        select new {p...., q......};
 

7voto

tvanfosson Points 268301

À l'aide de l'opérateur de jointure, vous pouvez uniquement effectuer equijoins. D'autres types de jointures peuvent être construits en utilisant d'autres opérateurs. Je ne suis pas sûr si la jointure que vous essayez de faire serait plus facile l'utilisation de ces méthodes ou par la modification de la clause where. Documentation sur la clause de jointure peut être trouvé ici. MSDN a un article sur les opérations de jointure avec de multiples liens à d'autres exemples de jointures, ainsi.

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