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