2008-09-18 44 views
5

談到作爲一個非C#精明的程序員,我很好奇,LINQ查詢的評價語義如下所示:LINQ-to-SQL支持可組合查詢嗎?

var people = from p in Person 
      where p.age < 18 
      select p 

var otherPeople = from p in people 
        where p.firstName equals "Daniel" 
        select p 

假設Person是定義agefirstName領域的ADO實體,是什麼這是從數據庫的角度來看嗎?具體而言,將運行people查詢以生成內存結構,然後將查詢​​查詢?或者​​的構建只是從people中提取有關查詢的數據,然後產生一個新的數據庫對等查詢?所以,如果我迭代了這兩個查詢,將執行多少個SQL語句?

回答

12

它們是可組合。這是可能的,因爲LINQ查詢實際上是表達式(代碼爲數據),LINQ提供者像LINQ-to-SQL可以評估和生成相應的SQL。

由於LINQ查詢懶洋洋地評估(例如不再執行,直到你遍歷元素),你的代碼表明將不實際接觸數據庫。直到你迭代其他人或人會SQL生成和執行。

1

people和​​包含IQueryable<Person>類型的對象。

如果您遍歷兩者separatly,它將運行兩個查詢。 如果您只遍歷​​,它將運行預期的查詢,並帶有兩個where子句。

如果您在people上做.ToList()並在第二個查詢中使用返回的List<Person>而不是人員,它將變成LINQ-to-Objects並且不執行SQL。

這種行爲被稱爲延遲執行。意思是在需要之前沒有查詢完成。在執行之前,它們只是表達式樹,被操縱來制定最終查詢。

0

這兩個查詢會在執行時,你會嘗試訪問最終結果。您可以嘗試查看從DataContext對象屬性生成的原始SQL。

3

是的,生成的查詢是組成的。它包含完整的where子句。打開SQL分析並嘗試查看自己。

的LINQ做到這一點通過表達式樹。第一個linq語句生成一個表達式樹;它不執行查詢。第二個linq語句建立在第一個創建的表達式樹上。該語句僅在枚舉生成的集合時執行。

3
var people = from p in Person 
      where p.age < 18 
      select p 

翻譯爲:

SELECT [t0].[PersonId], [t0].[Age], [t0].[FirstName] 
FROM [dbo].[Person] AS [t0] 
WHERE [t0].[Age] < @p0 

其中@ P0獲得通過的18

var otherPeople = from p in people 
        where p.firstName equals "Daniel" 
        select p 

發送轉換爲:

SELECT [t0].[PersonId], [t0].[Age], [t0].[FirstName] 
FROM [dbo].[Person] AS [t0] 
WHERE [t0].[FirstName] = @p0 

其中@ P0獲得通過爲發送「丹尼爾「

var morePeople = from p1 in people 
       from p2 in otherPeople 
       where p1.PersonId == p2.PersonId 
       select p1; 

翻譯爲:

SELECT [t0].[PersonId], [t0].[Age], [t0].[FirstName] 
FROM [dbo].[Person] AS [t0], [dbo].[Person] AS [t1] 
WHERE ([t0].[PersonId] = [t1].[PersonId]) AND ([t0].[Age] < @p0) AND ([t1].[FirstName] = @p1) 

其中@ P0是18,@ p1爲 「丹尼爾」

如有疑問,請致電您的IQueryable的toString()方法或者給一個TextWriter到DataContext的Log屬性。