2016-07-28 5 views
1

У меня есть таблица, которую мне нужно обобщить в отчете. Это моя таблица образцов.
Linq .GroupBy() со счетом

   Orders 
_____________________________________ 
CustomerId | CustomerName | OrderType 
___________|______________|__________ 
1   |  Adam  | Shoe 
1   |  Adam  | Shoe 
1   |  Adam  | Shoe 
1   |  Adam  | Hat 
1   |  Adam  | Hat 
2   |  Bill  | Shoe 
2   |  Bill  | Hat 
3   |  Carl  | Sock 
3   |  Carl  | Hat 

Я пытаюсь суммировать это передать обратно в мой ViewModel без петли. Это результат, которого я пытаюсь достичь.

CustomerName | Shoe | Hat | Sock | Total Orders 
------------ | ---- | --- | ---- | ------------ 
Adam   | 3 | 2 | 0 |  5 
Bill   | 1 | 1 | 0 |  2 
Carl   | 0 | 1 | 1 |  2 

//var resultList = dbContext.Orders.OrderBy(o => o.CustomerId); 

Как использовать GroupBy и Count для достижения желаемых результатов? Будет ли это лучшим подходом?

+0

включают текущий запрос что вы используете –

+1

согласитесь на @ не повезло .. и что вы работаете –

+2

Просьба уточнить, установлен ли список элементов только для этих 3 или вы хотите, чтобы количество столбцов менялось в зависимости от разных элементов. –

ответ

6

group clause (C# Reference)

var summary = from order in dbContext.Orders 
       group order by order.CustomerId into g 
       select new { 
        CustomerName = g.First().CustomerName , 
        Shoe = g.Count(s => s.OrderType == "Shoe"), 
        Hat = g.Count(s => s.OrderType == "Hat"), 
        Sock = g.Count(s => s.OrderType == "Sock"), 
        TotalOrders = g.Count() 
       }; 
+0

хорошее решение. Я изменил. Сначала() на .FirstOrDefault(). – pacopicorico

3

если элементы фиксируются:

public List<OrderViewModel> GetCustOrders() 
{ 
    var query = orders 
     .GroupBy(c => c.CustomerName) 
     .Select(o => new OrderViewModel{ 
      CustomerName = o.Key, 
      Shoe = o.Where(c => c.OrderType == "Shoe").Count(c => c.CustomerId), 
      Hat = o.Where(c => c.OrderType == "Hat").Count(c => c.CustomerId), 
      Sock = o.Where(c => c.OrderType == "Sock").Count(c => c.CustomerId), 
      Total = o.Count(c => c.CustomerId) 
     }); 

    return query; 
} 
0

использование SQL является одним из вариантов, я проверил его и получить именно то, что вы хотите:

select p.*, t.total as 'Total Orders' from 
(
    select CustomerName, count(CustomerId) total from Orders group by CustomerName 
) as t inner join 
(
    select * from Orders 
    pivot(count(CustomerId) 
     for OrderType in ([Shoe], [Hat], [Sock]) 
     ) as piv 
)as p on p.CustomerName = t.CustomerName 
Смежные вопросы