LINQ標準查詢操做符(二)——Join、GroupJoin、GroupBy、Concat、

4、聯接操做符

聯接是指將一個數據源對象與另外一個數據源對象進行關聯或者聯合的操做。這兩個數據源對象經過一個共同的值或者屬性進行關聯。sql

LINQ有兩個聯接操做符:Join和GroupJoin。spa

1. Join

Join操做符相似於T-SQL中的inner join,它將兩個數據源相聯接,根據兩個數據源中相等的值進行匹配。例如,能夠將產品表與產品類別表相聯接,獲得產品名稱和與其相對應的類別名稱。如下的代碼演示了這一點:code

複製代碼
            //查詢語法
            var query =
                (from p in db.Products
                 join c in db.Categories on p.CategoryID equals c.CategoryID
                 where p.CategoryID == 1
                 select new { p.ProductID, p.ProductName, c.CategoryID, c.CategoryName }).ToList();

生成的sql:
SELECT 
    [Extent1].[ProductID] AS [ProductID], 
    [Extent1].[ProductName] AS [ProductName], 
    [Extent2].[CategoryID] AS [CategoryID], 
    [Extent2].[CategoryName] AS [CategoryName]
    FROM  [dbo].[Products] AS [Extent1]
    INNER JOIN [dbo].[Categories] AS [Extent2] ON [Extent1].[CategoryID] = [Extent2].[CategoryID]
    WHERE (1 = [Extent1].[CategoryID]) AND ([Extent1].[CategoryID] IS NOT NULL)

            //方法語法
            var q =
                db.Products
                .Join
                (
                    db.Categories,
                    p => p.CategoryID,
                    c => c.CategoryID,
                    (p, c) => new { p.ProductID, p.ProductName, c.CategoryID, c.CategoryName }
                )
                .Where(p => p.CategoryID == 1)
                .ToList();

   生成的sql:
SELECT
    [Extent1].[ProductID] AS [ProductID],
    [Extent1].[ProductName] AS [ProductName],
    [Extent2].[CategoryID] AS [CategoryID],
    [Extent2].[CategoryName] AS [CategoryName]
    FROM  [dbo].[Products] AS [Extent1]
    INNER JOIN [dbo].[Categories] AS [Extent2] ON [Extent1].[CategoryID] = [Extent2].[CategoryID]
    WHERE 1 = [Extent2].[CategoryID]
複製代碼

以上代碼爲表述清晰加入了一個條件「where p.CategoryID == 1」,即僅返回產品類別ID爲1的全部產品。對象

生成的sql語句略有不一樣。blog

2. GroupJoin

GroupJoin操做符常應用於返回「主鍵對象-外鍵對象集合」形式的查詢,例如「產品類別-此類別下的全部產品」。如下的代碼演示了這一點:產品

複製代碼
            //查詢語法
            var query =
                (from c in db.Categories
                 join p in db.Products on c.CategoryID equals p.CategoryID into r
                 select new
                 {
                     c.CategoryName,
                     Products = r
                 }).ToList();
            //方法語法
            var q =
                db.Categories
                .GroupJoin
                (
                   db.Products,
                   c => c.CategoryID,
                   p => p.CategoryID,
                   (c, p) => new
                   {
                       c.CategoryName,
                       Products = p
                   }
                )
                .ToList();

生成的sql:
SELECT 
    [Project1].[CategoryID] AS [CategoryID], 
    [Project1].[CategoryName] AS [CategoryName], 
    [Project1].[C1] AS [C1], 
    [Project1].[ProductID] AS [ProductID], 
    [Project1].[ProductName] AS [ProductName], 
    [Project1].[SupplierID] AS [SupplierID], 
    [Project1].[CategoryID1] AS [CategoryID1], 
    [Project1].[QuantityPerUnit] AS [QuantityPerUnit], 
    [Project1].[UnitPrice] AS [UnitPrice], 
    [Project1].[UnitsInStock] AS [UnitsInStock], 
    [Project1].[UnitsOnOrder] AS [UnitsOnOrder], 
    [Project1].[ReorderLevel] AS [ReorderLevel], 
    [Project1].[Discontinued] AS [Discontinued]
    FROM ( SELECT 
        [Extent1].[CategoryID] AS [CategoryID], 
        [Extent1].[CategoryName] AS [CategoryName], 
        [Extent2].[ProductID] AS [ProductID], 
        [Extent2].[ProductName] AS [ProductName], 
        [Extent2].[SupplierID] AS [SupplierID], 
        [Extent2].[CategoryID] AS [CategoryID1], 
        [Extent2].[QuantityPerUnit] AS [QuantityPerUnit], 
        [Extent2].[UnitPrice] AS [UnitPrice], 
        [Extent2].[UnitsInStock] AS [UnitsInStock], 
        [Extent2].[UnitsOnOrder] AS [UnitsOnOrder], 
        [Extent2].[ReorderLevel] AS [ReorderLevel], 
        [Extent2].[Discontinued] AS [Discontinued], 
        CASE WHEN ([Extent2].[ProductID] IS NULL) THEN CAST(NULL AS int) ELSE 1 END AS [C1]
        FROM  [dbo].[Categories] AS [Extent1]
        LEFT OUTER JOIN [dbo].[Products] AS [Extent2] ON [Extent1].[CategoryID] = [Extent2].[CategoryID]
    )  AS [Project1]
    ORDER BY [Project1].[CategoryID] ASC, [Project1].[C1] ASC
複製代碼

返回的結果爲:
it

 

 

 

5、分組操做符

分組是根據一個特定的值將序列中的元素進行分組。LINQ只包含一個分組操做符:GroupByio

下面的示例中使用了產品表,以CategoryID做爲分組關鍵值,按照產品類別對產品進行了分組。class

 

複製代碼
            //查詢語法
            var query =
                (from p in db.Products
                 group p by p.CategoryID).ToList();
            //方法語法
            var q =
                db.Products
                .GroupBy(p => p.CategoryID)
                .ToList();

生成的sql:
SELECT 
    [Project2].[C1] AS [C1], 
    [Project2].[CategoryID] AS [CategoryID], 
    [Project2].[C2] AS [C2], 
    [Project2].[ProductID] AS [ProductID], 
    [Project2].[ProductName] AS [ProductName], 
    [Project2].[SupplierID] AS [SupplierID], 
    [Project2].[CategoryID1] AS [CategoryID1], 
    [Project2].[QuantityPerUnit] AS [QuantityPerUnit], 
    [Project2].[UnitPrice] AS [UnitPrice], 
    [Project2].[UnitsInStock] AS [UnitsInStock], 
    [Project2].[UnitsOnOrder] AS [UnitsOnOrder], 
    [Project2].[ReorderLevel] AS [ReorderLevel], 
    [Project2].[Discontinued] AS [Discontinued]
    FROM ( SELECT 
        [Distinct1].[CategoryID] AS [CategoryID], 
        1 AS [C1], 
        [Extent2].[ProductID] AS [ProductID], 
        [Extent2].[ProductName] AS [ProductName], 
        [Extent2].[SupplierID] AS [SupplierID], 
        [Extent2].[CategoryID] AS [CategoryID1], 
        [Extent2].[QuantityPerUnit] AS [QuantityPerUnit], 
        [Extent2].[UnitPrice] AS [UnitPrice], 
        [Extent2].[UnitsInStock] AS [UnitsInStock], 
        [Extent2].[UnitsOnOrder] AS [UnitsOnOrder], 
        [Extent2].[ReorderLevel] AS [ReorderLevel], 
        [Extent2].[Discontinued] AS [Discontinued], 
        CASE WHEN ([Extent2].[ProductID] IS NULL) THEN CAST(NULL AS int) ELSE 1 END AS [C2]
        FROM   (SELECT DISTINCT 
            [Extent1].[CategoryID] AS [CategoryID]
            FROM [dbo].[Products] AS [Extent1] ) AS [Distinct1]
        LEFT OUTER JOIN [dbo].[Products] AS [Extent2] ON ([Distinct1].[CategoryID] = [Extent2].[CategoryID]) OR (([Distinct1].[CategoryID] IS NULL) AND ([Extent2].[CategoryID] IS NULL))
    )  AS [Project2]
    ORDER BY [Project2].[CategoryID] ASC, [Project2].[C2] ASC
複製代碼

執行GroupBy獲得的序列中包含的元素類型爲IGrouping<TKey, T>,其Key屬性表明了分組時使用的關鍵值,遍歷IGrouping<TKey, T>元素能夠讀取到每個T類型。在此示例中,對應的元素類型爲IGrouping<int, Products>,其Key屬性即爲類別ID,遍歷它能夠讀取到每個產品對象。List

6、串聯操做符

串聯是一個將兩個集合聯接在一塊兒的過程。在LINQ中,這個過程經過Concat操做符來實現。

在下面的示例中,將會把類別名稱串聯在產品名稱以後:

複製代碼
//方法語法
            var q =
                db.Products
                .Select(p => p.ProductName)
                .Concat
               (
                    db.Categories.Select(c => c.CategoryName)
                )
                .ToList();

生成的sql:

SELECT 
    [UnionAll1].[ProductName] AS [C1]
    FROM  (SELECT 
        [Extent1].[ProductName] AS [ProductName]
        FROM [dbo].[Products] AS [Extent1]
    UNION ALL
        SELECT 
        [Extent2].[CategoryName] AS [CategoryName]
        FROM [dbo].[Categories] AS [Extent2]) AS [UnionAll1]
複製代碼

返回結果77+8=85

相關文章
相關標籤/搜索