2013-01-08 11 views
7

Desidero restituire un elenco di una determinata entità raggruppata da una determinata proprietà, ordinata decrescente per data/ora e impaginata (utilizzando Salta e Take). Quello che ho ottenuto è questa:Impaginazione di una query linq che utilizza OrderBy

container.CoinMessageSet.Where(
       c => c.MessageState != MessageStateType.Closed && 
        (c.DonorOperator.OperatorCode.Equals("opcode") || 
         c.RecipientOperator.OperatorCode.Equals("opcode")) 
       ).OrderByDescending(c => c.TimeStamp) 
       .GroupBy(c => c.Reference).Skip(x).Take(100); 

Al momento dell'esecuzione ho avuto l'eccezione:

The method 'Skip' is only supported for sorted input in LINQ to Entities. 
The method 'OrderBy' must be called before the method 'Skip'. 

... ho chiamato OrderBy() (anche se Discendente) e ho chiamato prima di Skip()! Cosa mi manca?

risposta

7

Non hai ordinato i gruppi; devi farlo prima che tu possa pagina. Per esempio:

.GroupBy(c => c.Reference).OrderBy(grp => grp.Key).Skip(x).Take(100); 

(si può anche sostituire OrderByDescending se si desidera che i gruppi in ordine inverso)

anche: dal momento che si esegue il raggruppamento, l'ordine dei dati originali è in gran parte privo di significato; probabilmente potresti rimuovere lo OrderByDescending(c => c.TimeStamp).

risultato così netto:

var query = container.CoinMessageSet.Where(
      c => c.MessageState != MessageStateType.Closed && 
       (c.DonorOperator.OperatorCode.Equals("opcode") || 
        c.RecipientOperator.OperatorCode.Equals("opcode")) 
      ).GroupBy(c => c.Reference).OrderBy(grp => grp.Key) 
      .Skip(x).Take(100); 

o, eventualmente:

var query = (from c in container.CoinMessageSet 
      where c.MessageState != MessageStateType.Closed && 
        (c.DonorOperator.OperatorCode == "opcode" || 
        c.RecipientOperator.OperatorCode == "opcode") 
      group c by c.Reference into grp 
      orderby grp.Key 
      select grp).Skip(x).Take(100); 
+0

Grazie per il chiarimento sulla questione originale, e realizzando ho uno nuovo;) (vale a dire 'devo ordinare da Timestamp, ma questo è in gran parte inutile a causa di Raggruppa per) –

2

E 'molto probabilmente a causa della GroupBy dopo il OrderByDescending.

penso che si può provare:

container.CoinMessageSet.Where(
       c => c.MessageState != MessageStateType.Closed && 
        (c.DonorOperator.OperatorCode.Equals("opcode") || 
         c.RecipientOperator.OperatorCode.Equals("opcode")) 
       ).OrderByDescending(c => c.TimeStamp) 
       .GroupBy(c => c.Reference).OrderByDescending(c = > c.Key).Skip(x).Take(100); 
Problemi correlati