Linq 下的 Take() 方法内部机制是怎样的?
咨詢區(qū)
Rahul Kishore:
我的web需要訪問數(shù)據(jù)庫,但是表比較大,我僅僅想要獲取該表中 N 條數(shù)據(jù),我查閱了 MSDN 文檔,看到了一個(gè) Take() 方法,我現(xiàn)在很疑惑它的運(yùn)行機(jī)制是下面哪一種?
先從數(shù)據(jù)庫中獲取所有記錄,然后在內(nèi)存中獲取 N 條記錄。
直接生成 TOP 關(guān)鍵詞到數(shù)據(jù)庫中。
請(qǐng)求大家的幫助。
回答區(qū)
Nic:
Take(N) 會(huì)在你的 sql 語句中添加 TOP N 關(guā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, 它是一個(gè)練習(xí) 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:
它會(huì)按照你認(rèn)為的最好預(yù)期去執(zhí)行的。
你的 Database SDK 引擎知道針對(duì)不同數(shù)據(jù)庫切換不同的查詢關(guān)鍵詞,比如說:對(duì)于 PostgreSQL, MySQL 或者 SQL Lite 這三種會(huì)生成 LIMIT,如果是 DB2 的話,會(huì)生成 "select first " + n + "from" ,如果是 Oracle 的話,又是 select * from (" + restOfQuery + ") where rownum <= " + n 。
只要有人針對(duì)某種數(shù)據(jù)庫寫了一套 linq to sql 引擎,所以只要引擎支持的語法,你都不需要過度擔(dān)心。
順便提一下,針對(duì)First()擴(kuò)展方法 ,SQL語句可能會(huì)變成 top 1 ,對(duì)于 Single() 方法,SQL語句可能會(huì)生成 top 2,這么做的原因是 sdk 引擎可以方便的測試當(dāng)前是不是 only 1,如果不是就會(huì)拋出異常。
點(diǎn)評(píng)區(qū)
現(xiàn)在連接數(shù)據(jù)庫的sdk已經(jīng)非常智能了,如果項(xiàng)目復(fù)雜度不高的話,大可以愉快的使用各種如 EntityFramework,Nhibernate,如果業(yè)務(wù)復(fù)雜度高,可以使用 Dapper 之類的半自動(dòng)化框架。
總結(jié)
以上是生活随笔為你收集整理的Linq 下的 Take() 方法内部机制是怎样的?的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Dapr牵手.NET学习笔记:Actor
- 下一篇: 基于事件驱动架构构建微服务第9部分:处理