Muszę wykonać zapytanie LINQ2DataSet, które wykonuje sprzężenie na więcej niż jednym polu (as
var result = from x in entity
join y in entity2
on x.field1 = y.field1
and
x.field2 = y.field2
Znalazłem jeszcze odpowiednie rozwiązanie (mogę dodać dodatkowe ograniczenia do klauzuli where, ale jest to dalekie od odpowiedniego rozwiązania lub użyć tego rozwiązania, ale zakłada ono ekwiwalinę).
Czy w LINQ jest możliwe łączenie wielu pól w jednym złączeniu?
EDYTOWAĆ
var result = from x in entity
join y in entity2
on new { x.field1, x.field2 } equals new { y.field1, y.field2 }
jest rozwiązaniem, o którym wspomniałem powyżej, zakładając ekwiwalent.
Dalsza edycja
Aby odpowiedzieć na krytykę, że mój oryginalny przykład był ekwioinem, potwierdzam, że moim obecnym wymogiem jest ekwiojon i już skorzystałem z rozwiązania, o którym wspominałem powyżej.
Staram się jednak zrozumieć, jakie możliwości i najlepsze praktyki mam / powinnam zastosować w LINQ. Niedługo będę musiał wykonać zapytanie dotyczące zakresu dat z identyfikatorem tabeli, a ja tylko uprzedziłem ten problem. Wygląda na to, że będę musiał dodać zakres dat w klauzuli where.
Dziękujemy, jak zawsze, za wszystkie sugestie i komentarze
Odpowiedzi:
Rozwiązanie z typem anonimowym powinno działać dobrze. LINQ może reprezentować tylko ekwizyty (w każdym razie z klauzulami przyłączenia), i tak naprawdę powiedziałeś, że i tak chcesz wyrazić na podstawie oryginalnego zapytania.
Jeśli nie podoba ci się wersja z typem anonimowym z jakiegoś konkretnego powodu, powinieneś to wyjaśnić.
Jeśli chcesz zrobić coś innego niż pierwotnie poprosiłeś, podaj przykład tego, co naprawdę chcesz zrobić.
EDYCJA: Odpowiadając na edycję w pytaniu: tak, aby wykonać łączenie „zakresu dat”, należy zamiast tego użyć klauzuli where. Są naprawdę semantycznie równoważne, więc to tylko kwestia dostępnych optymalizacji. Equijoins zapewniają prostą optymalizację (w LINQ do Objects, która obejmuje LINQ do DataSets) poprzez utworzenie wyszukiwania w oparciu o wewnętrzną sekwencję - pomyśl o tym jako o tablicy mieszającej od klucza do sekwencji wpisów pasujących do tego klucza.
Robienie tego z zakresami dat jest nieco trudniejsze. Jednak w zależności od dokładnie tego, co rozumiesz przez „dołączanie zakresu dat”, możesz być w stanie zrobić coś podobnego - jeśli planujesz utworzyć „pasma” dat (np. Jeden rocznie), tak że dwa wpisy, które występują w ten sam rok (ale nie w tym samym dniu) powinien pasować, możesz to zrobić, używając tego pasma jako klucza. Jeśli jest to bardziej skomplikowane, np. Jedna strona sprzężenia podaje zakres, a druga strona sprzężenia podaje pojedynczą datę, pasującą, jeśli mieści się w tym zakresie, lepiej byłoby użyć
where
klauzuli (po drugiejfrom
klauzula) IMO. Możesz wykonać jakąś szczególnie funkową magię, zlecając jednej lub drugiej stronie bardziej efektywne wyszukiwanie meczów, ale byłoby to dużo pracy - zrobiłbym to tylko po sprawdzeniu, czy wydajność jest problemem.źródło
źródło
on new { X1= x.field1, X2= x.field2 } equals new { X1=y.field1, X2= y.field2 }
zadziałałoMusisz to zrobić, jeśli nazwy kolumn są różne w dwóch jednostkach.
źródło
Aby zakończyć to równoważną składnią łańcucha metod:
Podczas gdy ostatni argument
(x, y) => x
jest tym, który wybierasz (w powyższym przypadku wybieramyx
).źródło
Myślę, że bardziej czytelną i elastyczną opcją jest użycie funkcji Where:
Pozwala to również na łatwą zmianę z łączenia wewnętrznego na lewe, dodając funkcję .DefaultIfEmpty ().
źródło
{ ... } equals new { ... }
składnia. LinqPad to świetne narzędzie do sprawdzania, jak zachowują się wyrażenia (skrypt SQL, jeśli używany jest LINQ2SQL, drzewa wyrażeń itp.)źródło
możesz zrobić coś takiego (poniżej)
źródło
Za pomocą operatora łączyć możesz wykonywać tylko ekwiwiny. Inne typy złączeń można konstruować przy użyciu innych operatorów. Nie jestem pewien, czy dokładne połączenie, które próbujesz wykonać, byłoby łatwiejsze przy użyciu tych metod lub poprzez zmianę klauzuli where. Dokumentację dotyczącą klauzuli przyłączenia można znaleźć tutaj . MSDN ma również artykuł na temat operacji łączenia z wieloma linkami do przykładów innych połączeń.
źródło
Jeśli nazwy pól są różne w jednostkach
źródło
Jako pełny łańcuch metod, który wyglądałby tak:
źródło
to działa dla mnie
źródło
Zadeklaruj klasę (typ), aby pomieścić elementy, które chcesz dołączyć. W poniższym przykładzie zadeklaruj JoinElement
źródło