2010-01-09 2 views
0

Я пытаюсь решить проблему «групповой макс» в LINQ. Для начала, у меня есть база данных, смоделированные с помощью Entity Framework со следующей структурой:Как найти групповой макс в LINQ?

Customer: 
--------- 
CustomerID : Int32 
Name : String 

Order: 
------- 
OrderID : Int32 
CustomerID : Int32 
Total : Decimal 

Это дает мне навигацию с Клиентом своих заказов и Распоряжения владельца.

Я пытаюсь создать запрос LINQ, который позволяет мне найти 10 лучших заказов клиентов в базе данных. Простой случай был довольно прост в использовании:

var q = (
    from order in _data.Orders // ObjectQuery<Order> 
    orderby order.Amount descending select order 
).Take(10); 

Однако я бы хотел показать только уникальные клиенты в этом списке. Я еще немного новичок в LINQ, но это то, что я придумал:

var q = (
    from order in _data.Orders // ObjectQuery<Order> 
    group order by order.Customer into o 
    select new { 
     Name = o.Key.Name, 
     Amount = o.FirstOrDefault().Amount 
    } 
).OrderByDescending(o => o.Amount).Take(10); 

Это похоже на работу, но я не уверен, что это лучший подход. В частности, я задаюсь вопросом о производительности такого запроса в отношении очень большой базы данных. Кроме того, использование метода FirstOrDefault из группового запроса выглядит немного странным ...

Может ли кто-нибудь обеспечить лучший подход или уверенность в том, что это правильный?

ответ

0

Вы можете сделать:

var q = (
    from order in _data.Orders // ObjectQuery<Order> 
    orderby order.Amount descending select order 
).Distinct().Take(10); 

Я обычно смотрю на сгенерированного SQL, и посмотреть, что является лучшим.

+0

Это вызывает большой вопрос ... Как посмотреть на сгенерированный SQL? С LINQ to SQL DataContext я могу записать вывод. Я не нашел способ сделать это для EF. – jheddings

+0

Hrm ... Попытавшись это, мне пришлось создать собственный компаратор равенства (поскольку по умолчанию он не работает для этой цели). Однако это исключает исключение, что EF не распознает этот метод. Есть идеи? – jheddings

0
Customer 
.Select(c=>new {Order= c.Orders.OrderByDescending(o=>o.Total).First()}) 
.OrderByDescending(o=>o.Total) 
.Take(10); 
Смежные вопросы