2012-09-04 4 views
12

Czy Aggregate zapytania VB.NET jest pełen wad stosowany jako pierwszej (zewnętrznej) klauzuli wyrażenia Linq z wielokrotności Into klauzule ponieważ każda klauzula Into jest wykonywany oddzielnie?Czy Aggregate jest fatalnie wadliwy, ponieważ każdy z nich jest wykonywany osobno?

z „oczywiste” odpowiedź na SELECT MIN(ZoneMin), MAX(ZoneMin) FROM Plant in LINQ to SQL jest

Dim limits = Aggregate p In Plants Select p.ZoneMin Into Min(), Max() 

Jednak ta odpowiedź faktycznie pobiera każdego Min i Max (a jeśli to inne kruszywa funkcje jak Count i Average) w oddzielnych zapytań SQL . Można to łatwo zauważyć w LINQPad.

Czy transakcja (lub coś innego powodującego, że zapytania te są niepodzielne) nie jest pokazywana przez LINQPad, czy jest to stan wyścigu, który czeka na realizację? (A więc trzeba robić triki pokazane w odpowiedzi na powyższe pytanie zmusić pojedynczą kwerendę, która zwraca wiele agregatów.)

Podsumowując, jest tam zapytań LINQ-SQL przy użyciu Aggregate że zwraca wiele kruszywo działa w jednym (lub przynajmniej "atomowym") zapytaniu?

(ja również powiedzieć „oczywiste”, ponieważ oczywista odpowiedź do mnie, Aggregate p In Plants Into Min(p.ZoneMin), Max(p.ZoneMin), faktycznie pobiera całą tabelę dwukrotnie, nawet jeśli zoptymalizowany, a następnie używa Linq-Podmiotów Min i Max aby uzyskać wynik: -()

Myślałem Aggregate nie była VB-specyficzny, ale wygląda na to, C# nie ma tego wyrażenia kwerendy, więc zmieniliśmy do

+0

Możesz być w stanie sprawdzić, czy zapytania są w transakcji, śledząc samego serwera SQL, powinien go pokazać (ale nie jestem w 100% pewny). Jeśli wydajność nie jest głównym problemem, lepiej jest przeczytać cały zestaw danych i następnie dokonać agregacji (zasadniczo, pracując nad migawką danych). – Alex

+0

Zauważ, że to właśnie miałem nadzieję, że moje oryginalne zapytanie 'Into Min (p.ZoneMin)' zoptymalizuje się do, ponieważ część zapytania SQL jest teraz taka sama. Być może JITter może nadal to widzieć, ale LINQPad's/o + nie. –

+0

A podczas agregowania tylko z funkcjami obsługiwanymi przez SQL, lepiej będzie "zgrupować według stałej sztuczki", aby uzyskać bazę danych do agregacji. –

Odpowiedz

0

Aby odpowiedzieć na moje szersze pytanie: czy jest Aggregate zepsute za wygenerowanie oddzielnych zapytań SQL bez transakcji?

Wszystko z LINQ może spowodować, że jeśli nie będziesz ostrożnie dostosowywał swoje zapytania, otrzymasz tylko jeden znak: SELECT, a to może nie być możliwe, bez "rezygnacji", pobrania większego wyniku w pojedynczym zapytaniu, a następnie używanie Linq-to-Objects do agregowania lub w inny sposób manipulowania danymi. This 'query' na przykład.

Zasadniczo programiści muszą zadbać o to, aby transakcje były dodawane wokół zapytań LINQ, które mogą powodować wiele zapytań. Musimy tylko wiedzieć, które zapytania LINQ mogą zostać przekształcone w wiele zapytań SQL.

1

Alt. Hough nie używać Agregat słowa kluczowego, można zrobić wiele funkcji w jednym zapytaniu, używając następującej składni:

Dim query = From book In books _ 
    Group By key = book.Subject Into Group _ 
    Select id = key, _ 
     BookCount = Group.Count, _ 
     TotalPrice = Group.Sum(Function(_book) _book.Price), _ 
     LowPrice = Group.Min(Function(_book) _book.Price), _ 
     HighPrice = Group.Max(Function(_book) _book.Price), _ 
     AveragePrice = Group.Average(Function(_book) _book.Price) 

Nie wydaje się być problem z Łącznej realizacji klauzuli chociaż. Rozważmy następującą kwerendę z Northwind:

Aggregate o in Orders 
into Sum(o.Freight), 
Average(o.Freight), 
Max(o.Freight) 

To wystawia 3 żądań bazy danych. Pierwsze dwa wykonują oddzielne klauzule agregujące. Trzeci wyciąga całą tabelę z powrotem do klienta i wykonuje Max na kliencie przez Linq do Objects.

+1

Tak, a jeśli zmienisz go na "Grupuj kluczem = 0 w grupę" (i upuść niepotrzebny "id = klucz"), otrzymasz "grupowanie według stałej" sztuczki opisane w odpowiedzi na pytanie, które mam o których mowa, pozwalając na agregację w całej tabeli. –

+0

W mojej próbce chcę grupy. Jeśli chcesz go przez cały stół, to twoja stała sztuczka działa dobrze. –

+0

Myślę, że * twój ostatni punkt jest związany z typem 'Frachtem ', a z jakiegoś powodu Linq jest zdania, że' MAX' w SQL może zwrócić inną wartość do tego, co według niego powinno powrócić 'Max'. Ale pytanie o moje zapytanie dotyczy _3 __separate__ database_. –

Powiązane problemy