Jak uzyskać wiersz MAX z funkcją GROUP BY w zapytaniu LINQ?

95

Szukam sposobu w LINQ, aby dopasować następujące zapytanie SQL.

Select max(uid) as uid, Serial_Number from Table Group BY Serial_Number

Naprawdę szukam pomocy w tej sprawie. Powyższe zapytanie pobiera maksymalny identyfikator użytkownika każdego numeru seryjnego ze względu na Group Byskładnię.

SpoiledTechie.com
źródło

Odpowiedzi:

94
        using (DataContext dc = new DataContext())
        {
            var q = from t in dc.TableTests
                    group t by t.SerialNumber
                        into g
                        select new
                        {
                            SerialNumber = g.Key,
                            uid = (from t2 in g select t2.uid).Max()
                        };
        }
tvanfosson
źródło
1
Chcę przyjąć oba jako odpowiedzi, ale chyba nie mogę, więc głosowałem na was oboje. Wielkie dzięki!!!
SpoiledTechie.com
70
var q = from s in db.Serials
        group s by s.Serial_Number into g
        select new {Serial_Number = g.Key, MaxUid = g.Max(s => s.uid) }
DamienG
źródło
Chcę przyjąć oba jako odpowiedzi, ale chyba nie mogę, więc głosowałem na was oboje. Wielkie dzięki!!!
SpoiledTechie.com
Zauważ również, że zmienną wyrażenia lambda => w funkcji Max może być dowolna wartość (s => s.uid, tv => tv.uid, asdf => asdf.uid). Linq automatycznie rozpozna to jako wybieranie elementów typu Serial.
Michael
30

W postaci łańcucha metod:

db.Serials.GroupBy(i => i.Serial_Number).Select(g => new
    {
        Serial_Number = g.Key,
        uid = g.Max(row => row.uid)
    });
Lu55
źródło
23

Sprawdziłem odpowiedź DamienG w LinqPad. Zamiast

g.Group.Max(s => s.uid)

Powinien być

g.Max(s => s.uid)

Dziękuję Ci!

denis_n
źródło
10
To prawdopodobnie powinno być komentarzem do odpowiedzi DamienG.
Cᴏʀʏ
11

Odpowiedzi są OK, jeśli potrzebujesz tylko tych dwóch pól, ale w przypadku bardziej złożonego obiektu może być przydatne takie podejście:

from x in db.Serials 
group x by x.Serial_Number into g 
orderby g.Key 
select g.OrderByDescending(z => z.uid)
.FirstOrDefault()

... pozwoli to uniknąć „wybierz nowy”

Javier
źródło
Podoba mi się to - czy wiesz, czy jest tak samo skuteczne, jak inne odpowiedzi?
noelicus
Użyłeś tutaj składni zapytania aż do końca, gdzie przełączyłeś się na składnię metody. Czy musiałeś? Czy dla Twojego rozwiązania jest pełna składnia zapytania?
Seth
0

Można to zrobić za pomocą GroupBy i SelectMany w wyrażeniu lamda LINQ

var groupByMax = list.GroupBy(x=>x.item1).SelectMany(y=>y.Where(z=>z.item2 == y.Max(i=>i.item2)));
Abhas Bhoi
źródło