關於第四章中,SQL指令何時執行小方框的補充說明

2021-04-16 23:13:06 字數 1903 閱讀 9971

關於第四章中,

sql指令何時執行小方框的補充說明

文/黃忠成

在【極意之道- .net framework 3.5 資料庫開發聖典 asp.net】一書中,我於第四章,4-36頁處放上sql指令何時執行的小方框,裡面的程式證明了當對同一linq to sql回傳值下達多次linq  expression表示式時,只有第一次會被轉成sql指令後送往資料庫執行。

但這點與前面提及的distinct、count、skip、take的函式之用法形成了概念上的衝突,例如下面的distinct函式用法。

var result = (from s1 in context.order_details

where s1.productid == 42 select s1.orderid).distinct().count();

依據4-b01的程式結果看來,distinct函式應該會先被執行,而count函式會進入linq to objects的範圍,但就事實而言,distinct及count函式都會被組合為單一sql指令。

select count(*) as [value]

from (

select distinct [t0].[orderid]

from [dbo].[order details] as [t0]

where [t0].[productid] = @p0

) as [t1]',n'@p0 int',@p0=42

那究竟是什麼,讓這兩個程式產生不同的結果呢?

事實上,這是因為4-b01的程式使用ienumerable為函式間傳遞之型別所致,對於編譯器來說,並不會以物件的原始型別來推算呼叫的extension method,而是以最終型別,意思是,當你將linq to sql的回傳值轉型為ienumerable後,那麼呼叫where時,編譯器將決議成呼叫system.linq.enumerable中的where函式,而非原本的iqueryable中的where函式。

所以,因為明白轉型成ienumerable後,使得編譯器將後續的linq expression全轉成了linq to objects的呼叫了。

要正確完成累進式查詢的方式,是將程式

4-b01

中的ienumerable全換成iqueryable。

static void nestedquery()

staticiqueryablegetfirstquery(northwinddatacontext context)

staticiqueryabledosecondquery(northwinddatacontext context,

iqueryablefirstquery)

這個例子告訴我們一件很重要的事,如果你打算將linq的回傳值傳遞到另乙個函式,或是回傳,要謹慎選擇型別,因為不同的型別,會影響後續使用linq時,編譯器如何決定呼叫的extension method,最後造成難以查覺的錯誤。

如果在撰寫linq/linq to sql的通用函式時,不得已需要使用ienumerable(因為這是linq回傳值的通用基礎介面),也要加上依據實體介面來轉型的動作,如下例:

static

void nestedquery()

static

ienumerable

getfirstquery(dataclasses1datacontext context)

static

ienumerable

dosecondquery(ienumerable

firstquery)

第四章 何時使用強制解封

本文系閱讀閱讀原章節後總結概括得出。由於需要我進行一定的概括提煉,如有不當之處歡迎讀者斧正。如果你對內容有任何疑問,歡迎共同交流討論。當你十分確定可選型別不會為nil,而且你希望一旦它為nil,你的程式就崩潰時,使用 強制解封可選型別。以上面的flateen方法為例 func flatten sou...

第四章 控制執行流程

3.迭代 do while 表示式第一次就為false,也執行一次 while 表示式第一次就為false,不執行 for 每次迴圈結束會執行一次步進,在初始化部分可以定義多個變數 例 for int i 1 int j i 10 i 5 i j i 2 5.return 指定方法返回值 導致當前方...

第四章 sql 動態查詢

declare va number 10 vb number 5 begin execute immediate create table temp1 a number 10 b number 5 execute immediate select a b from temp1 into va,vb ...