Ich muss eine LINQ2DataSet-Abfrage durchführen, die einen Join für mehr als ein Feld ausführt (as
var result = from x in entity
join y in entity2
on x.field1 = y.field1
and
x.field2 = y.field2
Ich habe noch eine geeignete Lösung gefunden (ich kann die zusätzlichen Einschränkungen zu einer where-Klausel hinzufügen, aber dies ist weit von einer geeigneten Lösung entfernt, oder ich verwende diese Lösung, aber dies setzt ein Äquijoin voraus).
Ist es in LINQ möglich, in einem einzigen Join mehreren Feldern beizutreten?
BEARBEITEN
var result = from x in entity
join y in entity2
on new { x.field1, x.field2 } equals new { y.field1, y.field2 }
ist die Lösung, auf die ich oben Bezug genommen habe.
Weitere EDIT
Um die Kritik zu beantworten, dass mein ursprüngliches Beispiel ein Equijoin war, erkenne ich an, dass meine derzeitige Anforderung ein Equijoin ist und ich bereits die Lösung verwendet habe, auf die ich oben verwiesen habe.
Ich versuche jedoch zu verstehen, welche Möglichkeiten und Best Practices ich bei LINQ habe / anwenden sollte. Ich muss bald einen Datumsbereichsabfrage-Join mit einer Tabellen-ID durchführen und habe dieses Problem nur vorweggenommen. Es sieht so aus, als müsste ich den Datumsbereich in der where-Klausel hinzufügen.
Vielen Dank wie immer für alle Vorschläge und Kommentare
Antworten:
Die Lösung mit dem anonymen Typ sollte gut funktionieren. LINQ kann nur Equijoins darstellen (jedenfalls mit Join-Klauseln), und tatsächlich haben Sie gesagt, dass Sie dies auf der Grundlage Ihrer ursprünglichen Abfrage sowieso ausdrücken möchten.
Wenn Ihnen die Version mit dem anonymen Typ aus einem bestimmten Grund nicht gefällt, sollten Sie diesen Grund erläutern.
Wenn Sie etwas anderes als das tun möchten, wonach Sie ursprünglich gefragt haben, geben Sie bitte ein Beispiel dafür, was Sie wirklich tun möchten.
BEARBEITEN: Antworten auf die Bearbeitung in der Frage: Ja, um einen "Datumsbereich" -Verbindungsvorgang durchzuführen, müssen Sie stattdessen eine where-Klausel verwenden. Sie sind wirklich semantisch äquivalent, es ist also nur eine Frage der verfügbaren Optimierungen. Equijoins bieten eine einfache Optimierung (in LINQ to Objects, einschließlich LINQ to DataSets), indem eine Suche basierend auf der inneren Sequenz erstellt wird. Stellen Sie sich diese als Hashtabelle vom Schlüssel zu einer Sequenz von Einträgen vor, die diesem Schlüssel entsprechen.
Das mit Datumsbereichen zu tun ist etwas schwieriger. Abhängig davon, was genau Sie unter einem "Datumsbereich-Join" verstehen, können Sie möglicherweise etwas Ähnliches tun - wenn Sie vorhaben, "Datumsbereiche" (z. B. einen pro Jahr) so zu erstellen, dass zwei Einträge in der Das gleiche Jahr (aber nicht am selben Datum) sollte übereinstimmen. Dann können Sie dies einfach tun, indem Sie dieses Band als Schlüssel verwenden. Wenn es komplizierter ist, z. B. eine Seite des Joins einen Bereich bereitstellt und die andere Seite des Joins ein einzelnes Datum bereitstellt, das übereinstimmt, wenn es in diesen Bereich fällt, wird dies besser mit einer
where
Klausel behandelt (nach einer Sekunde)from
Klausel) IMO. Sie könnten besonders funky zaubern, indem Sie der einen oder anderen Seite befehlen, Übereinstimmungen effizienter zu finden, aber das wäre eine Menge Arbeit - ich würde so etwas erst tun, nachdem ich überprüft habe, ob die Leistung ein Problem darstellt.quelle
quelle
on new { X1= x.field1, X2= x.field2 } equals new { X1=y.field1, X2= y.field2 }
funktionierte esSie müssen dies tun, wenn sich die Spaltennamen in zwei Entitäten unterscheiden.
quelle
Um dies mit einer äquivalenten Methodenkettensyntax zu vervollständigen:
Während das letzte Argument das
(x, y) => x
ist, was Sie auswählen (im obigen Fall wählen wirx
).quelle
Ich denke, eine lesbarere und flexiblere Option ist die Verwendung der Where-Funktion:
Dies ermöglicht auch den einfachen Wechsel vom inneren zum linken Join durch Anhängen von .DefaultIfEmpty ().
quelle
{ ... } equals new { ... }
Syntax haben. LinqPad ist ein großartiges Tool, um zu sehen, wie sich Ausdrücke verhalten (SQL-Skript, wenn LINQ2SQL verwendet wird, Ausdrucksbäume usw.)quelle
Sie könnten so etwas wie (unten) tun
quelle
Mit dem Join-Operator können Sie nur Equijoins ausführen. Andere Arten von Verknüpfungen können mit anderen Operatoren erstellt werden. Ich bin mir nicht sicher, ob der genaue Join, den Sie versuchen, mit diesen Methoden oder durch Ändern der where-Klausel einfacher wäre. Die Dokumentation zur Join-Klausel finden Sie hier . MSDN enthält einen Artikel zu Verknüpfungsvorgängen mit mehreren Links zu Beispielen für andere Verknüpfungen.
quelle
Wenn sich die Feldnamen in Entitäten unterscheiden
quelle
Als vollständige Methodenkette würde das so aussehen:
quelle
das funktioniert bei mir
quelle
Deklarieren Sie eine Klasse (Typ), die die Elemente enthält, denen Sie beitreten möchten. Im folgenden Beispiel deklarieren Sie JoinElement
quelle