Ho una chiamata dati in un livello di accesso ai dati basato su Linq to Entities che è progettato per effettuare chiamate pagate.
In tal modo, ho bisogno di selezionare un sottoinsieme dei dati, diciamo 50 righe, ma anche ottenere il conteggio di tutte le corrispondenze per sapere quante corrispondenze totali esistono per essere sfogliate.
Attualmente, sto facendo quanto segue:
var queryResult = DatabaseContext.Table
.Where(x => !x.IsDeleted)
.Where(p => (
p.PropertyOne.ToLower().Contains(query) ||
p.PropertyTwo.ToLower().Contains(query)
));
int count = queryResult.Count();
var returnData = queryResult
.OrderBy(i => i.ID)
.Skip(start).Take((length))
.Select(y => new ObjectDTO
{
PropertyOne = y.PropertyOne,
PropertyTwo = y.PropertyTwo
}
.AsEnumerable();
Ciò si traduce in due costose operazioni di database. L'operazione COUNT
per qualche motivo richiede effettivamente più tempo dell'operazione SELECT
.
C'è un modo per ottenere un conteggio e un sottoinsieme nella stessa operazione?
Il flusso logico per me dice che facciamo quanto segue:
Questo sembra possibile in una sola operazione, ma non riesco a capire come.
Tentativo Uno, più lento
Provato il suggerimento di D Stanley di lanciare il set completo di risultati in una List
e fare il conteggio e la memoria nel paging, ma è all'incirca 2x più lento (6.9 avg vs 3.9s avg)
Vale la pena ricordare che il set di dati è di circa 25.000 record, con oltre una dozzina di tabelle correlate che vengono cercate in un JOIN.
Potrebbe essere possibile, ma probabilmente non sarà molto più veloce a causa dei criteri che stai utilizzando. Poiché stai cercando testo all'interno di un valore di colonna, non puoi utilizzare un indice e quindi devi eseguire una scansione della tabella. Si può fare una singola query per ottenere tutti i record e fare il Count
e Skip/Take
in linq-to-oggetti:
var queryResult = DatabaseContext.Table
.Where(x => !x.IsDeleted)
.OrderBy(i => i.ID)
.Where(p => (
p.PropertyOne.ToLower().Contains(query) ||
p.PropertyTwo.ToLower().Contains(query)
))
.ToList();
int count = queryResult.Count(); // now this will be a linq-to-objects query
var returnData = queryResult
.Skip(start).Take((length))
.AsEnumerable();
ma dovresti provare per vedere se sarebbe più veloce.