跨关系查询
您的类定义中对其他对象或其他对象的集合的直接引用相当于数据库中的外键关系。 您可以通过使用点表示法在查询时利用这些关系来访问关系属性以及从一个对象定位到另一个对象。 这些访问操作会转换成用等效的 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 获得相同的结果,可以使用 Customer
类中已经存在的 Orders
属性引用。 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