生活随笔
收集整理的這篇文章主要介紹了
【转】 LINQ TO SQL中的selectMany
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
首先看SelectMany的定義:
? ? Queryable中的SelectMany 方法:將序列的每個元素投影到一個 IEnumerable<(Of <(T>)>) 并將結(jié)果序列組合為一個 IQueryable<(Of <(T>)>) 類型的序列。(引用MSDN)
? ? 在用LINQ TO SQL 來寫查詢語句時,有一個selectMany的語句,它標(biāo)示著一對多的關(guān)系,這篇文章我想說下在LINQ TO SQL中幾種可以等同selectMany的用法。
? ? ? 系統(tǒng)轉(zhuǎn)換成selectMany的條件:
? ? ? ? ? 1:語句中不包含join ,into;
? ? ? ? ? 2:需要2個以上的from:下面以兩個表為例:如第一個表from c in 表1
? ? ? ? ? ? 1):如果from的對象均用表名,(from c in 表2),則會轉(zhuǎn)換成cross join;
? ? ? ? ? ? 2):如果第二個表名以第一個表的子表形式出現(xiàn),即類似c.表2,這又分兩種情況,
? ? ? ? ? ? ? ? 1>:from o in c.表2,此時會形成inner join
? ? ? ? ? ? ? ? 2>:from p in c.表2.DefaultIfEmpty(),此時會形成LEFT OUT JOIN
? ? 文中例子表結(jié)構(gòu)說明:Customer表和Purchase表,通過ID與CustomerID建立關(guān)聯(lián)。
CREATE TABLE [dbo].[Customer](? ? [ID] [int] NOT NULL,? ? [Name] [nvarchar](30) ) CREATE TABLE [dbo].[Purchase](? ? [ID] [int] NOT NULL,? ? [CustomerID] [int] NULL,? ? [Date] [datetime] NOT NULL,? ? [Description] [varchar](30) ) 復(fù)制代碼
我們來實(shí)現(xiàn)SQL中的三種非常經(jīng)典的聯(lián)接方式。
? ? ? 第一:cross join,它的結(jié)果集是所有表的迪卡爾積。
//cross join? ? from c in Customers? ? from o in Purchases? ? select o 復(fù)制代碼
在LINQ TO SQL中,下面的from都指定為表名的話,就會生成下面的語句:
SELECT [t1].[ID], [t1].[CustomerID], [t1].[Date], [t1].[Description], [t1].[Price]FROM [Customer] AS [t0], [Purchase] AS [t1] 復(fù)制代碼
第二:inner join。
//inner join? ? from c in Customers? ? from o in c.Purchases? ? select o 復(fù)制代碼
生成的SQL如下:
SELECT [t1].[ID], [t1].[CustomerID], [t1].[Date], [t1].[Description], [t1].[Price]FROM [Customer] AS [t0], [Purchase] AS [t1]WHERE [t1].[CustomerID] = [t0].[ID] 復(fù)制代碼
雖然沒有顯示的用inner join,但和它的功能是一樣的.它的寫法和上面的cross join看起來特別像,唯一的區(qū)別就在于cross join時,直接用了表名Purchases,而inner join用的時候變成了c.Pruchasex,即形成了一對多的情況。
? ? 第三:? LEFT OUTER JOIN
from c in Customers? ? from p in c.Purchases.DefaultIfEmpty()? ? select new { c.Name, p.Description, Price = (decimal?) p.Price } 復(fù)制代碼
生成的SQL如下:
SELECT [t0].[Name], [t1].[Description] AS [Description], [t1].[Price] AS [Price]FROM [Customer] AS [t0]LEFT OUTER JOIN [Purchase] AS [t1] ON [t1].[CustomerID] = [t0].[ID] 復(fù)制代碼
left outer join實(shí)際上是在inner join的基礎(chǔ)上加了一個條件,利用DefaultIfEmpty(),當(dāng)記錄不匹配時,返回null
我們對上在的查詢增加一個過濾條件。
from c in Customersfrom p in c.Purchases.Where (p => p.Price > 1000).DefaultIfEmpty()select new{? ? c.Name,? ? p.Description,? ? Price = (decimal?) p.Price} 復(fù)制代碼
對應(yīng)的SQL:
SELECT [t0].[Name], [t1].[Description] AS [Description], [t1].[Price] AS [Price]FROM [Customer] AS [t0]LEFT OUTER JOIN [Purchase] AS [t1] ON ([t1].[Price] > @p0) AND ([t1].[CustomerID] = [t0].[ID]) 復(fù)制代碼
此時上面的語句還是標(biāo)準(zhǔn)的LEFT OUT JOIN,如果我們改變下條件的位置呢?
from c in Customersfrom p in c.Purchases.DefaultIfEmpty()where p.Price>1000select new{? ? c.Name,? ? p.Description,? ? Price = (decimal?) p.Price} 復(fù)制代碼
對應(yīng)的SQL:
SELECT [t0].[Name], [t1].[Description] AS [Description], [t1].[Price] AS [Price]FROM [Customer] AS [t0]LEFT OUTER JOIN [Purchase] AS [t1] ON [t1].[CustomerID] = [t0].[ID]WHERE [t1].[Price] > @p0 復(fù)制代碼
條件改變位置后并沒有改變join的本質(zhì),還是LEFT OUT JOIN,只不過查詢的結(jié)果不一樣了,從結(jié)果集上看,后面一種的效果和inner join的結(jié)果一樣。
? ? ? 總結(jié):上面的查詢語句也可以用顯示的join來查詢,個人更喜歡用顯示的join,因?yàn)橄啾容^SQL更接近些,看起來要親近些。在下篇文章中,我會總結(jié)顯示用join查詢的用法,其實(shí)最終的顯示結(jié)果都一樣,只是寫法不同。
文/姜敏? 出處/博客園
轉(zhuǎn)載于:https://www.cnblogs.com/JosephLiu/archive/2010/02/28/1675063.html
總結(jié)
以上是生活随笔為你收集整理的【转】 LINQ TO SQL中的selectMany的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。