Linq 下的 Take() 方法内部机制是怎样的?

咨询区

  • Rahul Kishore

我的web需要访问数据库,但是表比较大,我仅仅想要获取该表中 N 条数据,我查阅了 MSDN 文档,看到了一个 Take() 方法,我现在很疑惑它的运行机制是下面哪一种?

  1. 先从数据库中获取所有记录,然后在内存中获取 N 条记录。

  2. 直接生成 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 写法的好工具。

c35bc42fae52cb7e46d4040b36d0ef5e.png

更多可以参考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 之类的半自动化框架。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值