跨关系查询

在类定义中对其他对象或其他对象集合的引用直接对应于数据库中的外键关系。 使用点表示法访问关系属性并从一个对象导航到另一个对象时,可以使用这些关系。 这些访问操作转换为等效 SQL 中更复杂的连接或关联子查询。

例如,以下查询从订单导航到客户,以此将结果限制为仅针对位于伦敦的客户的那些订单。

        Northwnd db = new Northwnd(@"northwnd.mdf");

        IQueryable<Order> londonOrderQuery =
from ord in db.Orders
where ord.Customer.City == "London"
select ord;
    Dim db As New Northwnd("c:\northwnd.mdf")
    Dim londonOrderQuery = _
From ord In db.Orders _
Where ord.Customer.City = "London" _
Select ord

如果关系属性不存在,则必须像在 SQL 查询中那样手动编写 连接,就像以下代码所示:

        Northwnd db = new Northwnd(@"northwnd.mdf");
        IQueryable<Order> londonOrderQuery =
from cust in db.Customers
join ord in db.Orders on cust.CustomerID equals ord.CustomerID
where cust.City == "London"
select ord;
    Dim db As New Northwnd("c:\northwnd.mdf")
    Dim londOrderQuery = _
From cust In db.Customers _
Join ord In db.Orders On cust.CustomerID Equals ord.CustomerID _
Select ord

可以使用 关系 属性一次定义此特定关系。 然后,可以使用更方便的点语法。 但关系属性更为重要,因为特定于域的对象模型通常定义为层次结构或图形。 您针对其编程的对象具有对其他对象的引用。 对象与对象之间的关系恰好与数据库中的外键关系相对应,这仅仅是一种巧合。 然后,属性访问提供了一种编写联接的便捷方法。

对此,关系属性在查询的结果端比作为查询本身的一部分更重要。 查询检索到有关特定客户的数据后,类定义指示客户有订单。 换言之,您希望特定客户的 Orders 属性是用该客户下的所有订单填充的集合。 这实际上是您通过以此方式定义类声明的协定。 即便查询并未请求订单,您也希望在那里看到这些订单。 你希望对象模型保持一种假象,即它作为数据库的内存扩展,相关对象能够立即获取。

有了关系后,可以通过引用类中定义的关系属性来编写查询。 这些关系引用对应于数据库中的外键关系。 使用这些关系的操作会转换为等效 SQL 中更复杂的连接。 只要定义了关系(使用 AssociationAttribute 属性),就不必在 LINQ to SQL 中编写显式联接。

为了帮助保持这种错觉,LINQ to SQL 实现了一种称为 延迟加载的技术。 有关详细信息,请参阅 延迟加载与即时加载

请考虑以下 SQL 查询来生成 CustomerID-OrderID 对的列表:

SELECT t0.CustomerID, t1.OrderID  
FROM   Customers AS t0 INNER JOIN  
          Orders AS t1 ON t0.CustomerID = t1.CustomerID  
WHERE  (t0.City = @p0)  

若要使用 LINQ to SQL 获取相同的结果,请使用 Orders 类中 Customer 已存在的属性引用。 这个Orders引用提供了执行查询和映射CustomerID-OrderID对所需的信息,如以下代码所示:

        Northwnd db = new Northwnd(@"northwnd.mdf");
        var idQuery =
from cust in db.Customers
from ord in cust.Orders
where cust.City == "London"
select new { cust.CustomerID, ord.OrderID };
    Dim db As New Northwnd("c:\northwnd.mdf")
    Dim idQuery = _
From cust In db.Customers, ord In cust.Orders _
Where cust.City = "London" _
Select cust.CustomerID, ord.OrderID

你也可以执行逆向操作。 也就是说,可以查询 Orders 并使用其 Customer 关系引用来访问有关关联 Customer 对象的信息。 下面的代码投影与前面相同的 CustomerID-OrderID 对,但这一次采用的方法是查询 Orders 而非 Customers

        Northwnd db = new Northwnd(@"northwnd.mdf");
        var idQuery =
from ord in db.Orders
where ord.Customer.City == "London"
select new { ord.Customer.CustomerID, ord.OrderID };
    Dim db As New Northwnd("c:\northwnd.mdf")
    Dim idQuery = _
From ord In db.Orders _
Where ord.Customer.City = "London" _
Select ord.CustomerID, ord.OrderID

另请参阅