zoukankan      html  css  js  c++  java
  • EntityFramework查询联合查询(Join,GroupJoin)

    首先我们先看一下Join

    public static IEnumerable<TResult> Join<TOuter, TInner, TKey, TResult>(this IEnumerable<TOuter> outer, IEnumerable<TInner> inner, Func<TOuter, TKey> outerKeySelector, Func<TInner, TKey> innerKeySelector, Func<TOuter, TInner, TResult> resultSelector);

    第一个参数outer就是你连接的左面的集合,第二个inner是你要与之连接的集合,第三个outerKeySelector就是要用outer的哪个键来进行连接,第四个innerKeySelector同理,最后一个就是返回的类型。用法如下:

    NorthwindEntities dbContext = new NorthwindEntities();
    var data = dbContext.Employees.Join(dbContext.Orders, e => e.EmployeeID, o => o.EmployeeID, (e, o) => new { EmployeeID = e.EmployeeID, OrderID = o.OrderID, Address = o.ShipAddress, EmployeeAddress = e.Address });

    上面的代码对应的SQL语句如下:

    SELECT 
        [Extent1].[EmployeeID] AS [EmployeeID], 
        [Extent2].[OrderID] AS [OrderID], 
        [Extent2].[ShipAddress] AS [ShipAddress], 
        [Extent1].[Address] AS [Address]
    FROM  [dbo].[Employees] AS [Extent1]
    INNER JOIN [dbo].[Orders] AS [Extent2] ON [Extent1].[EmployeeID] = [Extent2].[EmployeeID]

    很明显是用的内连接方式,但是会不会有其他方式呢?那么再来一段代码看看:

    var data = dbContext.Employees.Join(dbContext.Orders, e => e.EmployeeID, o => o.EmployeeID, (e, o) => new { EmployeeID = e.EmployeeID, OrderID = o.OrderID });

    对应的SQL语句如下:

    SELECT 
        [Extent1].[EmployeeID] AS [EmployeeID], 
        [Extent1].[OrderID] AS [OrderID]
    FROM [dbo].[Orders] AS [Extent1]
    WHERE [Extent1].[EmployeeID] IS NOT NULL

    看到了吧,没有inner join了,本意是要查找Employee对应的订单,但是上面的代码只返回了EmpoloyeeID和OrderID,因为查找Employee对应的订单,本来就可以直接在Orders中查找的,所以EF还是对此代码做了优化,免去了inner join。

    既然连接已经写好了,那么要对返回的结果进行筛选你可以调用Where等扩展方法了。

    接下来看看GroupJoin

    public static IQueryable<TResult> GroupJoin<TOuter, TInner, TKey, TResult>(this IQueryable<TOuter> outer, IEnumerable<TInner> inner, Expression<Func<TOuter, TKey>> outerKeySelector, Expression<Func<TInner, TKey>> innerKeySelector, Expression<Func<TOuter, IEnumerable<TInner>, TResult>> resultSelector);

    来看个例子:

    Products表有一个CategoryID的属性,但是Category中并没要存储对应的ProductID,如果要查找Category下的Product我们该怎么做呢?如下:

    var data = dbContext.Categories.GroupJoin(dbContext.Products, c => c.CategoryID, p => p.CategoryID, (c, p) => new { CategoryID = c.CategoryID, ProductList = p });

    对应的SQL语句如下:

    SELECT 
    [Project1].[CategoryID] AS [CategoryID], 
    [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], 
        [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
    不明白外面为什么又嵌套一层select,完全可以将排序放到内侧的查询中的嘛,然后把外面查询给去掉就得了!
  • 相关阅读:
    软件开发记录04
    《敏捷软件需求》阅读笔记02
    软件开发记录03
    《敏捷软件需求》阅读笔记01
    软件开发记录02
    Leetcode
    Leetcode
    Leetcode
    leetcode -625-Minimum Factorization
    51Nod
  • 原文地址:https://www.cnblogs.com/linchong/p/2817270.html
Copyright © 2011-2022 走看看