Take()方法如何工作?

时间:2015-06-22 22:21:03

标签: c# .net entity-framework linq linq-to-entities

我有一个比较大的表我在我的网络应用程序中查询,我只想从表中返回 N 行数。

我已经阅读了MSDN文档,但是如果Take()首先从数据库中提取所有记录,或者它的行为与SQL Server类似,我就无法看到它的状态&# 39; s TOP

我担心如果Take()会提取所有记录,那么会获得最高 N 个记录,或者它会按预期运行直接检索 N 个记录数

4 个答案:

答案 0 :(得分:11)

请参阅Return Or Skip Elements in a Sequence

Take(N)会将TOP N添加到您的SQL中,并且只会检索N条记录。

例如(使用我自己的带有EF 6.1的SQL Server 2014):

这个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]

如果要确定LINQ正在生成哪种SQL,请使用SQL事件探查器(如果您正在使用SQL Server)。对于你编写的任何LINQ,这总是一个很好的做法。

SQL Profiler

答案 1 :(得分:3)

尽力而为。

由于您似乎正在使用SQL Server,并且其引擎知道SQL Server有TOP,因此它将使用它。它也可以在MS Access中使用它。

如果您使用的是PostgreSQL,MySQL或SQL Lite,则会使用LIMIT

它也可能在Oracle上使用"fetch first " + n + " rows only"(DB2和SQL:2008标准样式)或"select first " + n + "from"(Informix样式)或"select * from (" + restOfQuery + ") where rownum <= " + n或任何给定的数据库。

如果有人为数据库编写了一个绝对不能支持这种限制的引擎,那么它确实可以在获得所需的结果后关闭结果流。

无论哪种方式,它在特定情况下都能做到最好。

顺便提一下,对于1及其变体使用First()的相同方法,2及其变体的值Single()也是如此(因为您需要尝试至少使用2行来测试只有1行。

答案 2 :(得分:1)

它将直接检索N个记录。

的LINQ:

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

将生成以下SQL

select top 10 * from table

您可以使用SQL Server配置文件查看生成的查询,或者在调试器下运行时,IntelliTrace会显示SQL查询。

答案 3 :(得分:0)

以下是我每次使用的网格视图分页和酷炫的表现:

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