2012-03-22 11 views
6

In una griglia, ho bisogno di pagina su un record tramite il suo ID. Ecco perché ho bisogno di trovare il suo indice nel set filtrato dall'utente e ordinato dall'utente.Come ottenere l'indice di riga per chiave di entità in una query generata dinamicamente utilizzando Entity Framework

Sto lavorando con LINQ to Entities. La query viene creata dinamicamente, in base all'input dell'utente.

La tabella contiene troppi (più di 10^5), record per il seguente Stack Overflow suggestion di essere nulla di buono:

Recs = Recs.Where(/* Filters */); 
Recs = Recs.OrderBy(/* Sort criteria */); 
Recs.AsEnumerable() 
     .Select((x,index) => new {RowNumber = index, Record = x}) 
     .Where(x=>x.Record.ID = 35); 

Perché LINQ   a   Entità non supporta Select((entity, index) => ...), sarebbe necessario il download 250.000 record dal server SQL solo per poter decidere di mostrare la pagina 25.000.

Attualmente, la mia idea più promettente è quella di trasformare ciascun criterio di ordinamento in un filtro. Quindi trovare l'indice di una persona ordinata in base all'altezza crescente equivarrebbe a contare le persone più corte (criterio di classificazione 'altezza crescente' => filtro 'altezza inferiore a' + conteggio).

Come devo affrontare questo? Questo problema è già stato risolto? C'è qualche libreria per .NET che mi porta anche a metà strada lì?

+0

io non capisco quello che stai chiedendo, stai chiedendo come trovare il valore chiave per una particolare selezione di una pagina particolare? O stai cercando di capire il modo migliore per recuperare una singola pagina alla volta? – CodingGorilla

+0

Dato un id di riga/chiave di entità, voglio trovare la posizione di quella particolare riga in una query ordinata e filtrata. Supponiamo che l'utente decida di ordinare le persone per nome, la persona impostata è [{id: 11, nome: "Amy"}, {id: 1, nome "Joe"}, {id: 2, nome "Zack"}], dato l'id 11 ho bisogno di ottenere index = 1, id = 1 => index = 2, id = 2 => index = 3 –

+0

Ok, quindi hai l'id del database, devi trovare la riga corrispondente nell'interfaccia utente, destra? Qual è l'interfaccia utente, ASP.NET, WinForms, WPF? – CodingGorilla

risposta

2

Questa è una funzione ricorsiva che è possibile chiamare per calcolare il numero di riga. Se i record del tuo database cambiano frequentemente, probabilmente non funzionerà, dato che questo chiama più volte il database restringendo la ricerca a metà ogni volta.

public static int FindRowNumber<T>(IQueryable<T> query, Expression<Func<T, bool>> search, int skip, int take) 
{ 
    if(take < 1) return -1; 
    if(take == 1) return query.Skip(skip).Take(take).Any(search) ? skip : -1;  


    int bottomSkip = skip; 
    int bottomTake = take/2; 
    int topSkip = bottomTake + bottomSkip; 
    int topTake = take - bottomTake; 

    if(query.Skip(bottomSkip).Take(bottomTake).Any(search)) 
    {   
    return FindRowNumber(query, search, bottomSkip, bottomTake); 
    } 
    if(query.Skip(topSkip).Take(topTake).Any(search)) 
    { 
    return FindRowNumber(query, search, topSkip, topTake); 
    } 

    return -1; 
} 

Si chiama in questo modo:

var query = ... //your query with ordering and filtering 
int rownumber = FindRowNumber(query, x => x.Record.ID == 35, 0, query.Count()); 
+0

È un approccio interessante, ma non così veloce come quello che ho suggerito nella domanda, che finalmente ho implementato con (ab) utilizzando il sistema di filtraggio della griglia. D'altra parte, è visibilmente migliore dell'approccio nel mio frammento. Grazie per lo sforzo! –

+0

@ CălinDarie - Dovresti pubblicare la tua risposta e accettarla. Penso che le persone ne trarrebbero beneficio. – Aducci

Problemi correlati