dlaczego nie mógł projektanci LINQ dokonać rzeczy proste (więcej sql podobnych)
Mogli. Ale twoja definicja prostego (jako programista SQL) nie jest taka sama, jak definicja prostego programisty OO. Linq (w języku C#) to technologia zapytań dla programistów OO. Przykładem tego jest , dlaczego wybór przychodzi ostatni. To jest spełnienie reguł zasięgu w obsłudze C# i intellisense w edytorze.
Ci programiści być może nie dostaną LEFT JOIN
(i będą bardzo zdezorientowani, jeśli powiesz LEFT OUTER JOIN
- myśląc, że jest jakaś różnica, tak jak jedna dziedziczy po drugiej).
To, co rozumieją, to GROUP JOIN
, które zachowuje się w podobny sposób.
List<int> myInts = new List<int>() { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
List<int> myOtherInts = new List<int>() { 1, 3, 5, 7, 9, 11, 13 };
//
var query = from i in myInts
join j in myOtherInts on i equals j into g
select new {key = i, myGroup = g};
//
foreach (var grouping in query)
{
Console.WriteLine("--{0}", grouping.key);
foreach (var x in grouping.myGroup)
Console.WriteLine(x);
}
Wszystko to DefaultIfEmpty
robi rzeczy jest rozpakować grupę - spłaszczenie wyników w wiersz/kolumna formy - z dala od Komisarza programisty naturalnej postaci heirarchical.DefaultIfEmpty
nie jest semantycznie konieczne, aby uzyskać wyniki.
Oto to samo zapytanie w formie metody - które kompilator generuje z powyższego i które wolę:
var query = myInts.GroupJoin(
myOtherInts,
i => i,
j => j,
(i, g) => new { key = i, myGroup = g }
);
mógłbyś stwierdzić, że pod względem jego przykładem?
To zapytanie dostarcza klientom, z ich zamówieniami, jako załączoną kolekcję. Zbieranie zamówień może być puste. Jeśli masz 50 klientów i 1000 zamówień, w rezultacie uzyskasz 50 klientów.
from c in dc.Customers
join o in dc.Orders on c.custid equals o.custid into someOrders
select new CustomerWithOrders()
{theCustomer = c, theOrders = someOrders};
To zapytanie daje wiersz CustomerOrder. Jeśli klient ma 5 zamówień, klient pojawi się 5 razy, za każdym razem dopasowując się do innego zamówienia. Jeśli klient ma 0 zamówień, klient pojawi się po dopasowaniu do zamówienia zerowego. Jeśli masz 50 klientów i 1000 zamówień, po złączeniu będziesz miał 50-1049 wierszy, a znaczenie elementu w wyniku jest trudne do zdefiniowania.
from c in dc.Customers
join o in dc.Orders on c.custid equals o.custid into temp
from x in temp.DefaultIfEmpty()
select new CustomerOrderHybrid() {theCustomer = c, theOrder = x}
Jeśli one realizowane left join
, wymagałoby to kształt wynika z drugiego przykładu. Kiedyś użyłem group join
, co jest lepsze, nie wprowadziłbym też ani jednego kroku left join
. Hierarchiczne kształtowanie wyników zapytań jest świetne.
Tak, domyślam się, że to było prawdopodobnie trudne - chciałbym się dowiedzieć, dlaczego było to trudne ... – user52110
Linq nie jest cukrem syntaktycznym. kompilator nie tłumaczy niczego w wyrażeniach lambda. Nikt nie powiedział nic o generowaniu SQL w pytaniu. -1 –
OK, nie jestem pewien, że to lambdas per se, ale linq IS jest syntaktycznym cukrem i zostaje przetłumaczony na wywołania metod przez kompilator. –