跨表查询 (LINQ to DataSet)

除了查询单个表,还可以在 LINQ to DataSet 中执行跨表查询。 这可以通过使用“联接”来完成。 联接是一个数据源中的对象与共享另一数据源中的通用属性的对象(例如产品或联系人 ID)的关联。 在面向对象的编程中,对象之间的关系相对容易导航,因为每个对象都有引用另一个对象的成员。 但是,在外部数据库表中,导航关系并不简单。 数据库表不包含内置关系。 在这些情况下,联接操作可用于匹配每个来源中的元素。 例如,给定两个包含产品信息和销售信息的表,可以使用联接作来匹配同一销售订单的销售信息和产品。

Language-Integrated 查询(LINQ)框架提供两个联接运算符, Join 以及 GroupJoin。 这些运算符执行 等值联接:即,当两个数据源的键相等时,才进行联接。 (相比之下,Transact-SQL 支持除 equals之外的联接运算符,如 less than运算符。)

在关系数据库术语中, Join 实现内部联接。 内部联接是一种联接类型,其中仅返回那些在相反数据集中具有匹配项的对象。

操作符 GroupJoin 在关系数据库术语中没有直接对应的等效项;它们实现了内部联接和左外部联接的超集。 左外部联接是指返回第一个(左侧)集合的每个元素的联接,尽管第二个集合中没有关联元素。

有关联接的详细信息,请参阅联接操作

示例:

以下示例执行 AdventureWorks 示例数据库中的 SalesOrderHeaderSalesOrderDetail 表的传统联接,以获取 8 月份的在线订单。

// Fill the DataSet.
DataSet ds = new DataSet();
ds.Locale = CultureInfo.InvariantCulture;
FillDataSet(ds);

DataTable orders = ds.Tables["SalesOrderHeader"];
DataTable details = ds.Tables["SalesOrderDetail"];

var query =
    from order in orders.AsEnumerable()
    join detail in details.AsEnumerable()
    on order.Field<int>("SalesOrderID") equals
        detail.Field<int>("SalesOrderID")
    where order.Field<bool>("OnlineOrderFlag") == true
    && order.Field<DateTime>("OrderDate").Month == 8
    select new
    {
        SalesOrderID =
            order.Field<int>("SalesOrderID"),
        SalesOrderDetailID =
            detail.Field<int>("SalesOrderDetailID"),
        OrderDate =
            order.Field<DateTime>("OrderDate"),
        ProductID =
            detail.Field<int>("ProductID")
    };

foreach (var order in query)
{
    Console.WriteLine($"{order.SalesOrderID}\t{order.SalesOrderDetailID}\t{order.OrderDate:d}\t{order.ProductID}");
}
' Fill the DataSet.
Dim ds As New DataSet()
ds.Locale = CultureInfo.InvariantCulture
' See the FillDataSet method in the Loading Data Into a DataSet topic.
FillDataSet(ds)

Dim orders As DataTable = ds.Tables("SalesOrderHeader")
Dim details As DataTable = ds.Tables("SalesOrderDetail")


Dim query = _
    From order In orders.AsEnumerable() _
    Join detail In details.AsEnumerable() _
    On order.Field(Of Integer)("SalesOrderID") Equals _
            detail.Field(Of Integer)("SalesOrderID") _
    Where order.Field(Of Boolean)("OnlineOrderFlag") = True And _
            order.Field(Of DateTime)("OrderDate").Month = 8 _
    Select New With _
    { _
        .SalesOrderID = order.Field(Of Integer)("SalesOrderID"), _
        .SalesOrderDetailID = detail.Field(Of Integer)("SalesOrderDetailID"), _
        .OrderDate = order.Field(Of DateTime)("OrderDate"), _
        .ProductID = detail.Field(Of Integer)("ProductID") _
    }

For Each order In query
    Console.WriteLine(order.SalesOrderID & vbTab & _
        order.SalesOrderDetailID & vbTab & _
        order.OrderDate & vbTab & _
        order.ProductID)
Next

另请参阅