2015-06-22 21 views
7

Ho una tabella un po 'grande che sto interrogando nella mia app Web e voglio solo restituire il numero N di righe dalla tabella.Come funziona il metodo Take()?

Ho letto attraverso la documentazione MSDN, ma non riesco a vedere dove si afferma se Take() prima tira tutti i record dal DB, o se si comporta simile a SQL Server di TOP.

Sono preoccupato se Take() tirerà tutti i record, e quindi ottenere la parte superiore N numero di record o si comporterà come previsto e recuperare solo il N numero di record direttamente

+0

Si potrebbe utilizzare SQL Profiler per vedere il codice SQL che genera per voi stessi. Supponendo che chiami .Take() su un IQueryable, dovrebbe eseguire un TOP N contro SQL Server. Io uso sempre il profiler per garantire che Linq-SQL/Entities generi SQL semi-decente. – DaveShaw

+0

Cosa 'Take()' dipende dall'implementazione del database che stai usando e da come lo stai usando. Tutti quelli comuni che ho usato fanno la cosa giusta. –

+1

Quale "LINQ" stai usando? LINQ a SQL? Entity Framework? –

risposta

10

See Return Or Skip Elements in a Sequence.

Take(N) aggiungerà TOP N al proprio SQL e recupererà solo i record N.

Per esempio (usando il mio SQL Server 2014 con EF 6.1):

Questo LINQ:

var query = await dbContext.Lookup 
          .Where(w => w.LookupCd == '1') 
          .Take(10) 
          .ToListAsync(); 

genera questo SQL:

SELECT TOP (10) 
    [Extent1].[LookupId] AS [LookupId], 
    [Extent1].[LookupTypeId] AS [LookupTypeId], 
    [Extent1].[LookupCd] AS [LookupCd], 
    [Extent1].[LookupName] AS [LookupName], 
    [Extent1].[LookupDescription] AS [LookupDescription] 
FROM [dbo].[Lookup] AS [Extent1] 
WHERE '1' = [Extent1].[LookupCd] 

Utilizzare SQL Profiler (se si stai usando SQL Server) se vuoi essere sicuro di quale SQL sta generando il tuo LINQ. Questa è sempre una buona pratica con qualsiasi LINQ che scrivi.

SQL Profiler

+0

Ho appena provato a stampare la query var che avevo scritto nell'editor, l'ho mostrata tramite la Finestra Immediata e ne sono sicuro abbastanza stampato SELEZIONARE TOP! –

1

Si recupererà solo il numero N di record direttamente.

Linq: dbContext.table.Where (w => w.id == 1) .Take (10);

genererà il seguente SQL

selezionare top 10 * from tabella

è possibile vedere la query genereted usando Profile SQL Server o durante l'esecuzione in debugger, IntelliTrace mostra query SQL fatti.

spero che sia stato utile.

2

Lo fa meglio che può.

Poiché sembra che si stia utilizzando SQL Server e il suo motore sa che SQL Server dispone di un numero TOP, lo utilizzerà. Lo userebbe anche con MS Access.

Se si utilizza PostgreSQL, MySQL o SQL Lite, utilizzare LIMIT.

Potrebbe anche utilizzare "fetch first " + n + " rows only" (DB2 e SQL: 2008 stile standard) o "select first " + n + "from" (stile Informix) o "select * from (" + restOfQuery + ") where rownum <= " + n su Oracle o qualsiasi altra cosa un determinato database necessario.

E se qualcuno ha scritto un motore per un database che non poteva assolutamente supportare tali limiti, poteva effettivamente chiudere il flusso di risultati dopo aver preso ciò di cui aveva bisogno.

In entrambi i casi, fa il meglio che può nel caso particolare.

Inoltre, per inciso, utilizza lo stesso approccio con un valore di 1 per First() e le sue varianti e con un valore di 2 per Single() e le sue varianti (in quanto è necessario per cercare di prendere almeno 2 file per verificare che non ci è solo 1 a prendere).

0

Ecco quello che uso ogni volta per i miei GridView di paging con prestazioni cool:

resultList = context.MYTABLE.Where(WhereClause).OrderBy(orderCondition).Skip(firstItemIndex).Take(lastItemIndex - firstItemIndex + 1).ToList(); 
+1

Oltre a mostrare il codice, anche la mente spiega perché funziona. – SOFe