2016-03-26 15 views
2

Ich habe eine folgende Zeilen von abfallend Datum geordnet:Entity Framework - Skipwhile

var query = this.DbContext.Items.OrderByDescending(g => g.UpdatedAt); 

0 Dog  2016-03-08 
9 Cat  2016-03-07 
2 Elephant 2016-03-06 
8 Apple  2016-03-05 
3 Banana 2016-03-04 
7 Juice  2016-03-03 
4 Potato 2016-03-02 
5 Cafee  2016-03-01 

Die erste Abfrage gibt begrenzt (zum Beispiel 4) Anzahl der bestellten Elemente:

var result = query.Take(4).ToList(); 

0 Dog  2016-03-08 
9 Cat  2016-03-07 
2 Elephant 2016-03-06 
8 Apple  2016-03-05 

Die nächste Abfrage sollte Return limited (4) Anzahl der bestellten Elemente ab ID 3:

var result = query.ToList() 
      .SkipWhile(g => g.Id != startFrom.Value) 
      .Take(limit)); 

3 Banana 2016-03-04 
7 Juice  2016-03-03 
4 Potato 2016-03-02 
5 Cafee  2016-03-01 

Das Problem ist mit per formance, weil SkipWhile nicht von EF unterstützt wird, also muss ich zuerst alle Daten abrufen.

Natürlich kann ich schneiden alle älteren Reihen von:

var banana = this.Db.Context.Items.FirstOrDefault(g => g.Id == 3); 
var result = query.Where(g => g.CreatedAt < banana.CreatedAt).Take(limit); 

Ist es möglich, zu erreichen, dass durch einzelne, gut Leistung EF-Abfrage?

+1

Das Angeben von 'query.ToList()' zwingt EF, die Abfrage für die DB auszuführen. Versuchen Sie es mit '.Skip (4)'. Versuchen Sie, die Liste nach 4 Elementen zu durchsuchen? –

+0

Ich weiß nicht, wie viele Elemente übersprungen werden sollten. – Rakoo

Antwort

2

Zwei Aussagen führen nicht immer schlechter als eine, komplexe, Aussage, aber man kann dies tun:

var result = query.Where(g => g.CreatedAt < 
            this.DbContext.Items.FirstOrDefault(g2 => g2.Id == 3) 
           .CreatedAt) 
        .Take(limit); 

In der Tat ist es die einzige Möglichkeit ist, ich sehe SkipWhile Verhalten in einer SQL- zu imitieren freundliche Art.

Wenn Sie wirklich fest auf die Leistung sind, sollten Sie es auf die zweitbeste (oder vielleicht am besten) Option vergleichen:

var createdAt = this.Db.Context.Items 
        .Where(g => g.Id == 3) 
        .Select(g => g.CreatedAt) 
        .FirstOrDefault(); 
var result = query.Where(g => g.CreatedAt < createdAt).Take(limit); 

Dieses nur wählt einen Datumswert aus der Datenbank anstelle eines kompletten Item.

+0

Es kann nützlich sein. Vielen Dank. – Rakoo