Linq 下的 Take() 方法内部机制是怎样的?
Posted dotNET跨平台
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Linq 下的 Take() 方法内部机制是怎样的?相关的知识,希望对你有一定的参考价值。
咨询区
Rahul Kishore:
我的web需要访问数据库,但是表比较大,我仅仅想要获取该表中 N 条数据,我查阅了 MSDN 文档,看到了一个 Take()
方法,我现在很疑惑它的运行机制是下面哪一种?
先从数据库中获取所有记录,然后在内存中获取 N 条记录。
直接生成 TOP 关键词到数据库中。
请求大家的帮助。
回答区
Nic:
Take(N)
会在你的 sql 语句中添加 TOP N
关键词,这样你就可以获取前 N 条记录,参考如下 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 Server
的话,可以用 SQL Profiler
去捕获下生成出来的 SQL, 它是一个练习 LINQ 写法的好工具。
更多可以参考MSDN文档:https://docs.microsoft.com/en-us/dotnet/framework/data/adonet/sql/linq/return-or-skip-elements-in-a-sequence?redirectedfrom=MSDN
Jon Hanna:
它会按照你认为的最好预期去执行的。
你的 Database SDK
引擎知道针对不同数据库切换不同的查询关键词,比如说:对于 PostgreSQL, mysql 或者 SQL Lite 这三种会生成 LIMIT,如果是 DB2 的话,会生成 "select first " + n + "from"
,如果是 Oracle 的话,又是 select * from (" + restOfQuery + ") where rownum <= " + n
。
只要有人针对某种数据库写了一套 linq to sql 引擎,所以只要引擎支持的语法,你都不需要过度担心。
顺便提一下,针对First()
扩展方法 ,SQL语句可能会变成 top 1
,对于 Single()
方法,SQL语句可能会生成 top 2
,这么做的原因是 sdk 引擎可以方便的测试当前是不是 only 1
,如果不是就会抛出异常。
点评区
现在连接数据库的sdk已经非常智能了,如果项目复杂度不高的话,大可以愉快的使用各种如 EntityFramework,Nhibernate,如果业务复杂度高,可以使用 Dapper 之类的半自动化框架。
以上是关于Linq 下的 Take() 方法内部机制是怎样的?的主要内容,如果未能解决你的问题,请参考以下文章
使用 Linq Skip Take 进行传统 SQL 查询,而不是使用 RowNum