查询表达式语法示例:联接运算符

联接是面向相互之间没有可导航关系的数据源(如关系数据库表)的查询中的一项重要操作。 联接两个数据源就是将一个数据源中的对象与另一个数据源中具有相同公共属性的对象相关联。 有关详细信息,请参阅标准查询运算符概述

本主题中的示例演示如何使用 GroupJoinJoin 方法以使用查询表达式语法来查询 AdventureWorks 销售模型。 这些示例中使用的 AdventureWorks 销售模型从 AdventureWorks 示例数据库中的 Contact、Address、Product、SalesOrderHeader 和 SalesOrderDetail 等表生成。

本主题中的示例使用下面的 using/Imports 语句:

using System;
using System.Data;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Objects;
using System.Globalization;
using System.Data.EntityClient;
using System.Data.SqlClient;
using System.Data.Common;

Option Explicit On
Option Strict On
Imports System.Data.Objects
Imports System.Globalization

GroupJoin

示例

以下示例针对 SalesOrderHeader 表和 SalesOrderDetail 表执行 GroupJoin 以查找每个客户的订单数。 组联接等效于左外部联接,它返回第一个(左侧)数据源的每个元素(即使其他数据源中没有关联元素)。

using (AdventureWorksEntities context = new AdventureWorksEntities())
{
    ObjectSet<SalesOrderHeader> orders = context.SalesOrderHeaders;
    ObjectSet<SalesOrderDetail> details = context.SalesOrderDetails;

    var query =
        from order in orders
        join detail in details
        on order.SalesOrderID
        equals detail.SalesOrderID into orderGroup
        select new
        {
            CustomerID = order.SalesOrderID,
            OrderCount = orderGroup.Count()
        };

    foreach (var order in query)
    {
        Console.WriteLine("CustomerID: {0}  Orders Count: {1}",
            order.CustomerID,
            order.OrderCount);
    }
}
Using context As New AdventureWorksEntities
    Dim orders As ObjectSet(Of SalesOrderHeader) = context.SalesOrderHeaders
    Dim details As ObjectSet(Of SalesOrderDetail) = context.SalesOrderDetails

    Dim query = _
        From order In orders _
        Group Join detail In details _
        On order.SalesOrderID _
        Equals detail.SalesOrderID Into orderGroup = Group _
        Select New With _
        { _
            .CustomerID = order.SalesOrderID, _
            .OrderCount = orderGroup.Count() _
        }

    For Each order In query
        Console.WriteLine("CustomerID: {0}  Orders Count: {1}", _
            order.CustomerID, order.OrderCount)
    Next
End Using

示例

下面的示例对 Contact 和 SalesOrderHeader 表执行 GroupJoin 以查找每个联系人的订单数。 将显示每个联系人的订单数和 ID。

using (AdventureWorksEntities context = new AdventureWorksEntities())
{
    ObjectSet<Contact> contacts = context.Contacts;
    ObjectSet<SalesOrderHeader> orders = context.SalesOrderHeaders;

    var query =
        from contact in contacts
        join order in orders
        on contact.ContactID
        equals order.Contact.ContactID into contactGroup
        select new
        {
            ContactID = contact.ContactID,
            OrderCount = contactGroup.Count(),
            Orders = contactGroup
        };

    foreach (var group in query)
    {
        Console.WriteLine("ContactID: {0}", group.ContactID);
        Console.WriteLine("Order count: {0}", group.OrderCount);
        foreach (var orderInfo in group.Orders)
        {
            Console.WriteLine("   Sale ID: {0}", orderInfo.SalesOrderID);
        }
        Console.WriteLine("");
    }
}
Using context As New AdventureWorksEntities
    Dim contacts As ObjectSet(Of Contact) = context.Contacts
    Dim orders As ObjectSet(Of SalesOrderHeader) = context.SalesOrderHeaders

    Dim query = _
        From contact In contacts _
        Group Join order In orders _
        On contact.ContactID _
        Equals order.Contact.ContactID Into contactGroup = Group _
        Select New With { _
            .ContactID = contact.ContactID, _
            .OrderCount = contactGroup.Count(), _
            .Orders = contactGroup.Select(Function(order) order)}

    For Each group In query
        Console.WriteLine("ContactID: {0}", group.ContactID)
        Console.WriteLine("Order count: {0}", group.OrderCount)

        For Each orderInfo In group.Orders
            Console.WriteLine("   Sale ID: {0}", orderInfo.SalesOrderID)
        Next

        Console.WriteLine("")
    Next
End Using

联接

示例

以下示例针对 SalesOrderHeader 表和 SalesOrderDetail 表执行联接,以获得八月份的联机订单。

using (AdventureWorksEntities context = new AdventureWorksEntities())
{
    ObjectSet<SalesOrderHeader> orders = context.SalesOrderHeaders;
    ObjectSet<SalesOrderDetail> details = context.SalesOrderDetails;

    var query =
        from order in orders
        join detail in details
        on order.SalesOrderID equals detail.SalesOrderID
        where order.OnlineOrderFlag == true
        && order.OrderDate.Month == 8
        select new
        {
            SalesOrderID = order.SalesOrderID,
            SalesOrderDetailID = detail.SalesOrderDetailID,
            OrderDate = order.OrderDate,
            ProductID = detail.ProductID
        };

    foreach (var order in query)
    {
        Console.WriteLine("{0}\t{1}\t{2:d}\t{3}",
            order.SalesOrderID,
            order.SalesOrderDetailID,
            order.OrderDate,
            order.ProductID);
    }
}
Using context As New AdventureWorksEntities
    Dim orders As ObjectSet(Of SalesOrderHeader) = context.SalesOrderHeaders
    Dim details As ObjectSet(Of SalesOrderDetail) = context.SalesOrderDetails

    Dim query = _
        From ord In orders _
        Join det In details _
        On ord.SalesOrderID Equals det.SalesOrderID _
        Where ord.OnlineOrderFlag = True _
                And ord.OrderDate.Month = 8 _
        Select New With _
        { _
            .SalesOrderID = ord.SalesOrderID, _
            .SalesOrderDetailID = det.SalesOrderDetailID, _
            .OrderDate = ord.OrderDate, _
            .ProductID = det.ProductID _
        }

    For Each ord In query
        Console.WriteLine("{0}" & vbTab & "{1}" & vbTab & "{2:d}" & vbTab & "{3}", _
            ord.SalesOrderID, _
            ord.SalesOrderDetailID, _
            ord.OrderDate, _
            ord.ProductID)
    Next
End Using

请参阅