日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

【转】 LINQ TO SQL中的selectMany

發布時間:2025/5/22 数据库 19 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【转】 LINQ TO SQL中的selectMany 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

首先看SelectMany的定義:

? ? Queryable中的SelectMany 方法:將序列的每個元素投影到一個 IEnumerable<(Of <(T>)>) 并將結果序列組合為一個 IQueryable<(Of <(T>)>) 類型的序列。(引用MSDN)


? ? 在用LINQ TO SQL 來寫查詢語句時,有一個selectMany的語句,它標示著一對多的關系,這篇文章我想說下在LINQ TO SQL中幾種可以等同selectMany的用法。

? ? ? 系統轉換成selectMany的條件:
? ? ? ? ? 1:語句中不包含join ,into;
? ? ? ? ? 2:需要2個以上的from:下面以兩個表為例:如第一個表from c in 表1
? ? ? ? ? ? 1):如果from的對象均用表名,(from c in 表2),則會轉換成cross join;
? ? ? ? ? ? 2):如果第二個表名以第一個表的子表形式出現,即類似c.表2,這又分兩種情況,
? ? ? ? ? ? ? ? 1>:from o in c.表2,此時會形成inner join
? ? ? ? ? ? ? ? 2>:from p in c.表2.DefaultIfEmpty(),此時會形成LEFT OUT JOIN

? ? 文中例子表結構說明:Customer表和Purchase表,通過ID與CustomerID建立關聯。

  • 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) )
  • 復制代碼

    我們來實現SQL中的三種非常經典的聯接方式。


    ? ? ? 第一:cross join,它的結果集是所有表的迪卡爾積。

  • //cross join
  • ? ? from c in Customers
  • ? ? from o in Purchases
  • ? ? select o
  • 復制代碼

    在LINQ TO SQL中,下面的from都指定為表名的話,就會生成下面的語句:

  • SELECT [t1].[ID], [t1].[CustomerID], [t1].[Date], [t1].[Description], [t1].[Price]
  • FROM [Customer] AS [t0], [Purchase] AS [t1]
  • 復制代碼

    第二:inner join。

  • //inner join
  • ? ? from c in Customers
  • ? ? from o in c.Purchases
  • ? ? select o
  • 復制代碼

    生成的SQL如下:

  • SELECT [t1].[ID], [t1].[CustomerID], [t1].[Date], [t1].[Description], [t1].[Price]
  • FROM [Customer] AS [t0], [Purchase] AS [t1]
  • WHERE [t1].[CustomerID] = [t0].[ID]
  • 復制代碼

    雖然沒有顯示的用inner join,但和它的功能是一樣的.它的寫法和上面的cross join看起來特別像,唯一的區別就在于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 }
  • 復制代碼

    生成的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]
  • 復制代碼

    left outer join實際上是在inner join的基礎上加了一個條件,利用DefaultIfEmpty(),當記錄不匹配時,返回null
    我們對上在的查詢增加一個過濾條件。

  • from c in Customers
  • from p in c.Purchases.Where (p => p.Price > 1000).DefaultIfEmpty()
  • select new
  • {
  • ? ? c.Name,
  • ? ? p.Description,
  • ? ? Price = (decimal?) p.Price
  • }
  • 復制代碼

    對應的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])
  • 復制代碼

    此時上面的語句還是標準的LEFT OUT JOIN,如果我們改變下條件的位置呢?

  • from c in Customers
  • from p in c.Purchases.DefaultIfEmpty()
  • where p.Price>1000
  • select new
  • {
  • ? ? c.Name,
  • ? ? p.Description,
  • ? ? Price = (decimal?) p.Price
  • }
  • 復制代碼

    對應的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
  • 復制代碼

    條件改變位置后并沒有改變join的本質,還是LEFT OUT JOIN,只不過查詢的結果不一樣了,從結果集上看,后面一種的效果和inner join的結果一樣。

    ? ? ? 總結:上面的查詢語句也可以用顯示的join來查詢,個人更喜歡用顯示的join,因為相比較SQL更接近些,看起來要親近些。在下篇文章中,我會總結顯示用join查詢的用法,其實最終的顯示結果都一樣,只是寫法不同。

    文/姜敏? 出處/博客園

    轉載于:https://www.cnblogs.com/JosephLiu/archive/2010/02/28/1675063.html

    總結

    以上是生活随笔為你收集整理的【转】 LINQ TO SQL中的selectMany的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。