2012-01-23 28 views
5

Załóżmy, że mam poniższej tabeli:Grupa By, Sum w LINQ

user type amount 
2 a 10 
2 b 20 
2 c 40 
3 a 15 
3 b 20 
3 c 45 

chcę wymienić (c) kwotę z (c - (a + b)) grupowania przez użytkownika i rodzaju, w jaki sposób Robię to? Dzięki

+1

w LINQ do SQL, czy masz już dane w typie kolekcji (a więc LINQ to Objects)? –

+0

Przypuszczam, że masz na myśli, że chcesz grupować według wartości użytkownika, ponieważ wszystkie kombinacje użytkownika i typu są niepowtarzalne? – Guffa

+0

LINQ do SQL, jest to generowane przez gatunek datatable – moeezed

Odpowiedz

4

Oto sposób:

UPDATE (teraz za pomocą Sum):

from item in table 
group item by item.user into g 
let a = (from i in g where i.type == "a" select i.amount).Sum() 
let b = (from i in g where i.type == "b" select i.amount).Sum() 
let c = (from i in g where i.type == "c" select i.amount).Sum() 
select c - (a + b); 
+0

Zakładam, że może być wiele wpisów na użytkownika każdego typu. –

+0

Nie zakładałem, że ponieważ PO nie określił tego. W takim przypadku zapytanie będzie inne (prawdopodobnie 'Sum' zamiast' Single'). – Steven

+0

Zakładałem to, ponieważ mówi on o "SUM" w tytule pytania. Jego ostatni komentarz potwierdza moje przypuszczenie. –

0

Proponuję ekspansję na odpowiedź Steven „s, ponieważ będzie tylko powrót sekwencję wartości skalarnych c i nie przechowywać ich razem z użytkownikami lub kwotami a i b. Spróbuj tego:

var query1 = from i in table 
      group i by i.user 
      into g 
      let a = g.Where(t => t.type == "a").Sum(t => t.amount) 
      let b = g.Where(t => t.type == "b").Sum(t => t.amount) 
      let c = g.Where(t => t.type == "c").Sum(t => t.amount) 
        - (a + b) 
      select new {user = g.Key, a, b, c}; 

Następnie, jeśli chcesz, aby przekształcić go z powrotem do postaci tabelarycznej:

var query2 = query1.SelectMany(q => new List<TableType> 
            { 
             new TableType(q.user, "a", q.a), 
             new TableType(q.user, "b", q.b), 
             new TableType(q.user, "c", q.c) 
            }) 
            .OrderBy(t => t.user) 
            .ThenBy(t => t.type); 

Uwaga: Przetestowałem to i to działa.