2015-06-22 36 views
7

Mam dość duży stół, którego szukam w mojej aplikacji internetowej, i chcę tylko zwrócić N liczbę wierszy z tabeli.Jak działa metoda Take()?

Czytałem poprzez dokumentacji MSDN, ale nie mogę zobaczyć, gdzie stwierdza się, jeśli Take() najpierw ściąga wszystkie rekordy z bazy danych, czy też zachowuje się podobnie jak SQL Server TOP.

Martwię jeśli Take() będzie ciągnąć wszelkie rekordy, a następnieuzyskać najlepsze N liczba rekordów lub będą zachowywać się zgodnie z oczekiwaniami i pobrać tylko te N liczba rekordów bezpośrednio

+0

Można użyć SQL Profiler zobaczyć SQL to generuje dla siebie. Zakładając, że wywołasz .Take() na IQueryable, powinien wykonać TOP N wobec SQL Server. Zawsze używam profilera, aby zapewnić, że Linq-SQL/Entities generuje przyzwoity SQL. – DaveShaw

+0

Co 'Take()' zależy od używanej implementacji bazy danych i od tego, jak go używasz. Wszystkie typowe, z których korzystałem, są słuszne. –

+1

Którego "LINQ" używasz? LINQ do SQL? Entity Framework? –

Odpowiedz

10

Zobacz Return Or Skip Elements in a Sequence.

Take(N) doda TOP N do Twojego SQL i tylko pobierze rekordy N.

Na przykład (stosując własne SQL Server 2014 z EF 6.1):

Ten LINQ:

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

Generuje to 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] 

Użyj SQL Profiler (jeżeli korzystam z SQL Server), jeśli chcesz mieć pewność, jaki SQL generuje Twój LINQ. Jest to zawsze dobra praktyka z każdym LINQ, który piszesz.

SQL Profiler

+0

Po prostu próbowałem wydrukować zapytanie var, które napisałem w edytorze, wyświetlałem je przez okno natychmiastowe i na pewno to wydrukowano WYBIERZ GÓRĘ! –

1

To będzie pobierać tylko liczbę N rekordów bezpośrednio.

Linq: dbContext.table.W tym miejscu (w => w.id == 1) .Take (10);

będzie generować następujące SQL

select top 10 * z tabeli

widać wygenerowano za pomocą zapytania SQL Server profilu lub podczas jazdy pod debugger, IntelliTrace pokazuje wykonanych zapytań SQL.

Mam nadzieję, że było pomocne.

2

Robi to najlepiej, jak potrafi.

Ponieważ wydaje się, że używasz programu SQL Server, a jego silnik wie o tym, że serwer SQL Server ma numer TOP. Używałby tego również z MS Access.

Jeśli korzystasz z PostgreSQL, MySQL lub SQL Lite, użyjesz LIMIT.

Może również używać "fetch first " + n + " rows only" (styl standardowy DB2 i SQL: 2008) lub "select first " + n + "from" (Styl Informix) lub "select * from (" + restOfQuery + ") where rownum <= " + n na Oracle lub jakiejkolwiek innej wymaganej bazie danych.

A jeśli ktoś napisał silnik bazy danych, która absolutnie nie mogła obsługiwać takich limitów, to rzeczywiście mógł zamknąć strumień wyników po tym, jak wziął to, czego potrzebował.

Tak czy inaczej, robi to, co może w danym przypadku.

też, nawiasem mówiąc, używa tego samego podejścia z wartością 1 dla First() i jego odmian i o wartości 2 dla Single() i jego warianty (ponieważ trzeba się starać co najmniej 2 wiersze do przetestowania, że ​​nie jest tylko 1 do wzięcia).

0

Oto co mogę użyć za każdym razem dla moich gridviews stronicowania z chłodnym usług:

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

Oprócz pokazywania kodu, należy również pamiętać, wyjaśniając, dlaczego to działa. – SOFe

Powiązane problemy