2014-12-14 5 views
5

Angenommen, ich möchte meine Kundendatenbank nach Ländern ordnen. In SQL würde ich schreiben:Gibt es eine Funktion in Entity Framework, die die RANK() - Funktion in SQL übersetzt?

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

Jetzt möchte ich dies in Entity Framework schreiben:

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}); 

Es gibt zwei Probleme:

  1. Es funktioniert nicht. EF wirft eine System.NotSupportedException; offensichtlich gibt es keine SQL-Übersetzung für die overload of .Select(), die die Zeilennummer verwendet; Sie müssten alles mit einer .ToList() in den Speicher holen, um diese Methode aufrufen zu können; und
  2. Auch wenn Sie die Methode im lokalen Speicher ausführen, behandelt es nicht gleichrangig wie die RANK()-Funktion in SQL, d. h. sie sollten einen gleichen Rang haben, und das folgende Element überspringt dann die ursprüngliche Reihenfolge.

Also wie soll ich das tun?

+2

AKAIK Rank() hat keine eingebaute Funktion in LINQ. Diese Antwort verwendet Ihren Ansatz, aber es scheint für sie zu funktionieren: http://StackOverflow.com/a/21035060/7720 oder diese Frage hat mehrere Optionen. – Romias

+0

@Romias hast du mich auf die Spur gesetzt, um [diese Antwort] (http://stackoverflow.com/a/10705535/7850) zu finden, die mein Problem gelöst hat. Bitte zögern Sie nicht, es als Antwort hier zu schreiben, damit ich Ihnen Kredit geben kann! –

+0

Froh ich helfe dir ... Ich habe den Kommentar als Antwort gesetzt! Vielen Dank! – Romias

Antwort

3

AFAIK Rank() hat keine eingebaute Funktion in LINQ. This answer verwendet Ihren Ansatz, aber es scheint für sie zu arbeiten. Hier ist, wie Sie es verwenden könnten:

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

Danke! Ich habe einen Code hinzugefügt, damit Sie sehen können, dass er angewendet wurde. –