J'ai besoin de faire une requête LINQ2DataSet qui fait une jointure sur plusieurs champs (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é de solution appropriée (je peux ajouter les contraintes supplémentaires à une clause where, mais c'est loin d'être une solution appropriée, ou utiliser cette solution, mais cela suppose une équijoin).
Est-il possible dans LINQ de se joindre à plusieurs champs en une seule jointure?
ÉDITER
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ée en supposant une équijoin ci-dessus.
De plus EDIT
Pour répondre aux critiques selon lesquelles mon exemple d'origine était une équijoin, je reconnais que, Mon exigence actuelle est pour une équijoin et j'ai déjà utilisé la solution que j'ai mentionnée ci-dessus.
J'essaie cependant de comprendre quelles possibilités et meilleures pratiques j'ai / devrais utiliser avec LINQ. Je vais devoir bientôt faire une jointure de requête de plage de dates avec un ID de table, et je devais juste anticiper ce problème.Il semble que je devrai ajouter la plage de dates dans la clause where.
Merci, comme toujours, pour toutes les suggestions et commentaires donnés
Réponses:
La solution avec le type anonyme devrait fonctionner correctement. LINQ ne peut représenter que des équijointures (avec des clauses de jointure, de toute façon), et c'est d'ailleurs ce que vous avez dit que vous souhaitez exprimer de toute façon en fonction de votre requête d'origine.
Si vous n'aimez pas la version avec le type anonyme pour une raison spécifique, vous devez expliquer cette raison.
Si vous voulez faire autre chose que ce que vous aviez initialement demandé, veuillez donner un exemple de ce que vous voulez vraiment faire.
EDIT: Répondre à la modification dans la question: oui, pour faire une jointure "plage de dates", vous devez utiliser une clause where à la place. Ils sont vraiment sémantiquement équivalents, donc c'est juste une question d'optimisations disponibles. Les équijoins fournissent une optimisation simple (dans LINQ to Objects, qui comprend LINQ to DataSets) en créant une recherche basée sur la séquence interne - pensez-y comme une table de hachage de clé à une séquence d'entrées correspondant à cette clé.
Faire cela avec des plages de dates est un peu plus difficile. Cependant, selon exactement ce que vous entendez par "jointure de plage de dates", vous pourrez peut-être faire quelque chose de similaire - si vous prévoyez de créer des "bandes" de dates (par exemple une par an) de sorte que deux entrées qui se produisent dans le la même année (mais pas à la même date) devrait correspondre, alors vous pouvez le faire simplement en utilisant cette bande comme clé. Si c'est plus compliqué, par exemple, un côté de la jointure fournit une plage, et l'autre côté de la jointure fournit une seule date, correspondant si elle se situe dans cette plage, ce serait mieux géré avec une
where
clause (après une secondefrom
clause) OMI. Vous pourriez faire de la magie particulièrement funky en commandant un côté ou l'autre pour trouver des correspondances plus efficacement, mais ce serait beaucoup de travail - je ne ferais ce genre de chose qu'après avoir vérifié si les performances sont un problème.la source
la source
on new { X1= x.field1, X2= x.field2 } equals new { X1=y.field1, X2= y.field2 }
Cela a fonctionnéVous devez le faire si les noms de colonne sont différents dans deux entités.
la source
Juste pour compléter cela avec une syntaxe de chaîne de méthode équivalente:
Alors que le dernier argument
(x, y) => x
est ce que vous sélectionnez (dans le cas ci-dessus, nous sélectionnonsx
).la source
Je pense qu'une option plus lisible et flexible consiste à utiliser la fonction Where:
Cela permet également de passer facilement de la jointure interne à la jointure gauche en ajoutant .DefaultIfEmpty ().
la source
{ ... } equals new { ... }
syntaxe. LinqPad est un excellent outil pour voir comment les expressions se comportent (script SQL si LINQ2SQL est utilisé, arborescences d'expressions, etc.)la source
vous pourriez faire quelque chose comme (ci-dessous)
la source
En utilisant l'opérateur de jointure, vous ne pouvez effectuer que des équijointures. D'autres types de jointures peuvent être construits à l'aide d'autres opérateurs. Je ne sais pas si la jointure exacte que vous essayez de faire serait plus facile à utiliser ces méthodes ou en changeant la clause where. La documentation sur la clause join peut être trouvée ici . MSDN a également un article sur les opérations de jointure avec plusieurs liens vers des exemples d'autres jointures.
la source
Si le nom du champ est différent dans les entités
la source
En tant que chaîne de méthode complète qui ressemblerait à ceci:
la source
ça marche pour moi
la source
Déclarez une classe (type) pour contenir les éléments que vous souhaitez joindre. Dans l'exemple ci-dessous, déclarez JoinElement
la source