2015-06-22 5 views
7

У меня есть несколько большая таблица, которую я запрашиваю в своем веб-приложении, и я хочу только вернуть N количество строк из таблицы.Как работает метод Take()?

Я прочитал документацию MSDN, но я не могу понять, где он указывает, если Take() сначала извлекает все записи из БД или ведет себя аналогично SQL Server TOP.

Я беспокоюсь, если Take() будет тянуть все записи, а затем получить верхнюю N число записей или он будет вести себя, как ожидается, и получать только N количество записей непосредственно

+0

Вы можете использовать SQL Profiler, чтобы увидеть SQL он создает для себя. Предполагая, что вы вызываете .Take() в IQueryable, он должен выполнить TOP N против SQL Server. Я всегда использую профилировщик, чтобы гарантировать, что Linq-SQL/Entities генерирует полупристойный SQL. – DaveShaw

+0

Что делает 'Take()', зависит от используемой вами реализации баз данных и того, как вы ее используете. Все распространенные, которые я использовал, делают правильно. –

+1

Какую версию «LINQ» вы используете? LINQ to SQL? Entity Framework? –

ответ

10

Посмотреть Return Or Skip Elements in a Sequence.

Take(N) добавит TOP N к вашему SQL и только получит N записей.

Например (используя свой собственный SQL Server 2014 с EF 6.1):

Это LINQ:

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

Формирует этот 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] 

Используйте SQL Profiler (если вы используя SQL Server), если вы хотите быть уверенным в том, что SQL генерирует LINQ. Это всегда хорошая практика с любым LINQ, который вы пишете.

SQL Profiler

+0

Я просто попробовал распечатать запрос var, который я написал в редакторе, отображал его через окно Immediate и, распечатано SELECT TOP! –

1

Он будет получать только N число записей непосредственно.

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

будет генерировать следующий SQL

выбрать топ-10 * из таблицы

вы можете увидеть genereted запроса с использованием профиля SQL Server или при запуске под отладчиком, IntelliTrace показывает SQL запросов, сделанных.

Надеюсь, это было полезно.

2

Он делает это как можно лучше.

Поскольку вы, похоже, используете SQL Server, и его движок знает, что SQL Server имеет TOP, он будет использовать это. Он также будет использовать это с MS Access.

Если вы использовали PostgreSQL, MySQL или SQL Lite, он использовал бы LIMIT.

Он также может использовать "fetch first " + n + " rows only" (стандартный стиль DB2 и SQL: 2008) или "select first " + n + "from" (стиль Informix) или "select * from (" + restOfQuery + ") where rownum <= " + n для Oracle или любой другой конкретной базы данных.

И если кто-то написал двигатель для базы данных, который абсолютно не мог поддерживать такие ограничения, то он действительно мог бы закрыть поток результатов после того, как он принял то, что ему нужно.

В любом случае, он делает все возможное в конкретном случае.

Это тоже, кстати, использует тот же подход со значением 1 для First() и его варианты и со значением 2 для Single() и его вариантов (так как вам нужно, чтобы попытаться принять по крайней мере, 2 строки, чтобы проверить, что всего 1).

0

Вот что я использую каждый раз для моих GridViews пейджинга с прохладной производительностью:

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

В дополнение к показу кода, также разум объясняет, почему он работает. – SOFe

Смежные вопросы