2014-12-14 24 views
5

Giả sử tôi muốn xếp hạng cơ sở dữ liệu khách hàng của tôi theo quốc gia. Trong SQL Tôi sẽ viết:Có một chức năng trong khung thực thể chuyển thành hàm RANK() trong SQL không?

select CountryID, CustomerCount = count(*), 
     [Rank] = RANK() over (order by count(*) desc) 
from Customer 

Bây giờ tôi muốn viết những dòng này trong Entity Framework:

var ranks = db.Customers 
    .GroupBy(c => c.CountryID) 
    .OrderByDescending(g => g.Count()) 
    .Select((g, index) => new {CountryID = g.Key, CustomerCount = g.Count, Rank = index+1}); 

Có hai vấn đề với điều này:

  1. Nó không làm việc. EF ném System.NotSupportedException; rõ ràng không có bản dịch SQL cho số overload of .Select() sử dụng số hàng; bạn sẽ phải kéo mọi thứ vào bộ nhớ với một số .ToList() để có thể gọi phương thức này; và
  2. Thậm chí nếu bạn chạy phương thức trong bộ nhớ cục bộ, nó không xử lý thứ hạng như nhau theo cách mà hàm RANK() thực hiện trong SQL, nghĩa là chúng phải có thứ hạng bằng nhau, sau đó mục sau sẽ bỏ qua thứ tự ban đầu.

Vậy tôi nên làm như thế nào?

+2

AKAIK Rank() không có hàm dựng sẵn trong LINQ. Câu trả lời này sử dụng cách tiếp cận của bạn, nhưng nó có vẻ làm việc cho họ: http://stackoverflow.com/a/21035060/7720 hoặc câu hỏi này có một số tùy chọn. – Romias

+0

@Romias bạn đặt tôi trên đường mòn để tìm [câu trả lời này] (http://stackoverflow.com/a/10705535/7850) đã giải quyết được sự cố của tôi. Xin vui lòng viết nó như là một câu trả lời ở đây để tôi có thể cung cấp cho bạn tín dụng! –

+0

Vui vì tôi giúp bạn ... Tôi đặt bình luận là một câu trả lời! Cảm ơn! – Romias

Trả lời

3

AFAIK Rank() không có hàm dựng sẵn trong LINQ. This answer sử dụng cách tiếp cận của bạn, nhưng nó có vẻ làm việc cho họ. Dưới đây là cách bạn có thể sử dụng:

var customersByCountry = db.Customers 
    .GroupBy(c => c.CountryID); 
    .Select(g => new { CountryID = g.Key, Count = g.Count() }); 
var ranks = customersByCountry 
    .Select(c => new 
     { 
      c.CountryID, 
      c.Count, 
      Rank = customersByCountry.Count(c2 => c2.Count > c.Count) + 1 
     }); 
+0

Cảm ơn! Tôi đã thêm một số mã để bạn có thể thấy nó được áp dụng. –

Các vấn đề liên quan