2012-09-13 4 views
5

Ich habe einige Probleme mit einer langsamen Abfrage in Entity Framework in C#. Ich habe eine Erweiterungsmethode mit dem Namen Page erstellt, um Paging zu handhaben, aber wenn ich es benutze, wird die Abfrage sehr langsam. Wenn ich einfach .Skip (page.Value * pageSize.Value) .Take (pageSize.Value) statt mit Page die Abfrage wird viel schneller. Ich nehme an, dass es alle Seiten vor dem Paging holt, wenn Sie mit Page arbeiten. Gibt es eine Möglichkeit dies zu verhindern oder mache ich etwas anderes falsch?Entity Framework Paging mit der Erweiterungsmethode ist langsam?

Abfrage:

var contacts = db.Contacts 
         .Where(x => x.AccountID == accountID && x.Deleted == false) 
         .OrderByDescending(x => x.FirstName) 
         .ThenBy(x => x.LastName) 
         .ThenBy(x => x.CreatedDate) 
         .Page(page, pageSize); 

return contacts.ToList(); 

Erweiterungsmethode:

public static IEnumerable<T> Page<T>(this IEnumerable<T> elements, int? page, int? pageSize) 
    { 
     if (page.HasValue && pageSize.HasValue) 
      return elements.Skip(page.Value * pageSize.Value).Take(pageSize.Value); 
     else 
      return elements; 
    } 

Antwort

9

Ihre Erweiterungsmethode sollte über IQueryable sein, so dass EF den Ausdruck verarbeiten kann und die SQL-Abfrage mit Paginierung erzeugen.

Da Sie IEnumerable verwenden, ruft die Page-Methode Skip and Take von IEnumerable auf. Dies führt zu einer Aufzählung des Ergebnisses der Abfrage, die bis zu diesem Punkt aufgebaut wurde (vor dem Aufruf von Page) und die Paginierung im Speicher über alle zurückgegebenen Elemente durchführt, anstatt die Seitennummerierung in die DB-Abfrage einzubeziehen.