查询表达式语法示例:导航关系
实体框架中的导航属性是快捷方式属性,用于定位位于关联各端的实体。 导航属性允许用户通过关联集从一个实体导航到另一个实体或从一个实体导航到多个相关的实体。 本主题以查询表达式语法提供相关的示例,以介绍如何通过 LINQ to Entities 查询中的导航属性来导航关系。
这些示例中使用的 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
示例 1
以下示例使用 Select 方法以获取所有联系人 ID 和姓氏为“Zhou”的每个联系人的应付款总计。 Contact.SalesOrderHeader
导航属性用于获取每个联系人的 SalesOrderHeader
对象的集合。 Sum
方法使用 Contact.SalesOrderHeader
导航属性以汇总每个联系人的所有订单的应付款总计。
string lastName = "Zhou";
using (AdventureWorksEntities context = new AdventureWorksEntities())
{
ObjectSet<Contact> contacts = context.Contacts;
var ordersQuery = from contact in contacts
where contact.LastName == lastName
select new
{
ContactID = contact.ContactID,
Total = contact.SalesOrderHeaders.Sum(o => o.TotalDue)
};
foreach (var contact in ordersQuery)
{
Console.WriteLine($"Contact ID: {contact.ContactID} Orders total: {contact.Total}");
}
}
Dim lastName = "Zhou"
Using context As New AdventureWorksEntities
Dim contacts As ObjectSet(Of Contact) = context.Contacts
Dim ordersQuery = From contact In contacts _
Where contact.LastName = lastName _
Select New With _
{.ContactID = contact.ContactID, _
.Total = contact.SalesOrderHeaders.Sum(Function(o) o.TotalDue)}
For Each order In ordersQuery
Console.WriteLine("Contact ID: {0} Orders total: {1}", order.ContactID, order.Total)
Next
End Using
示例 2
以下示例获取其姓氏为“Zhou”的联系人的所有订单。 Contact.SalesOrderHeader
导航属性用于获取每个联系人的 SalesOrderHeader
对象的集合。 联系人的姓名和订单以匿名类型返回。
string lastName = "Zhou";
using (AdventureWorksEntities context = new AdventureWorksEntities())
{
ObjectSet<Contact> contacts = context.Contacts;
var ordersQuery = from contact in contacts
where contact.LastName == lastName
select new { LastName = contact.LastName, Orders = contact.SalesOrderHeaders };
foreach (var order in ordersQuery)
{
Console.WriteLine($"Name: {order.LastName}");
foreach (SalesOrderHeader orderInfo in order.Orders)
{
Console.WriteLine("Order ID: {0}, Order date: {1}, Total Due: {2}",
orderInfo.SalesOrderID, orderInfo.OrderDate, orderInfo.TotalDue);
}
Console.WriteLine("");
}
}
Dim lastName = "Zhou"
Using context As New AdventureWorksEntities
Dim contacts As ObjectSet(Of Contact) = context.Contacts
Dim ordersQuery = From contact In contacts _
Where contact.LastName = lastName _
Select New With _
{.LastName = contact.LastName, _
.Orders = contact.SalesOrderHeaders}
For Each order In ordersQuery
Console.WriteLine("Name: {0}", order.LastName)
For Each orderInfo In order.Orders
Console.WriteLine("Order ID: {0}, Order date: {1}, Total Due: {2}", _
orderInfo.SalesOrderID, orderInfo.OrderDate, orderInfo.TotalDue)
Next
Console.WriteLine("")
Next
End Using
示例 3
以下示例使用 SalesOrderHeader.Address
和 SalesOrderHeader.Contact
导航属性以获取与每个订单关联的 Address
对象和 Contact
对象的集合。 Seattle 城市发生的每个订单的联系人姓氏、街道地址、销售订单号和应付款总计将以匿名类型返回。
string city = "Seattle";
using (AdventureWorksEntities context = new AdventureWorksEntities())
{
ObjectSet<SalesOrderHeader> orders = context.SalesOrderHeaders;
var ordersQuery = from order in orders
where order.Address.City == city
select new
{
ContactLastName = order.Contact.LastName,
ContactFirstName = order.Contact.FirstName,
StreetAddress = order.Address.AddressLine1,
OrderNumber = order.SalesOrderNumber,
TotalDue = order.TotalDue
};
foreach (var orderInfo in ordersQuery)
{
Console.WriteLine("Name: {0}, {1}", orderInfo.ContactLastName, orderInfo.ContactFirstName);
Console.WriteLine($"Street address: {orderInfo.StreetAddress}");
Console.WriteLine($"Order number: {orderInfo.OrderNumber}");
Console.WriteLine($"Total Due: {orderInfo.TotalDue}");
Console.WriteLine("");
}
}
Dim city = "Seattle"
Using context As New AdventureWorksEntities
Dim orders As ObjectSet(Of SalesOrderHeader) = context.SalesOrderHeaders
Dim ordersQuery = From order In orders _
Where order.Address.City = city _
Select New With { _
.ContactLastName = order.Contact.LastName, _
.ContactFirstName = order.Contact.FirstName, _
.StreetAddress = order.Address.AddressLine1, _
.OrderNumber = order.SalesOrderNumber, _
.TotalDue = order.TotalDue}
For Each orderInfo In ordersQuery
Console.WriteLine("Name: {0}, {1}", orderInfo.ContactLastName, orderInfo.ContactFirstName)
Console.WriteLine("Street address: {0}", orderInfo.StreetAddress)
Console.WriteLine("Order number: {0}", orderInfo.OrderNumber)
Console.WriteLine("Total Due: {0}", orderInfo.TotalDue)
Console.WriteLine("")
Next
End Using
示例 4
以下示例使用 Where
方法以查找在 2003 年 12 月 1 日之后生成的订单,然后使用 order.SalesOrderDetail
导航属性以获取每个订单的详细信息。
using (AdventureWorksEntities context = new AdventureWorksEntities())
{
IQueryable<SalesOrderHeader> query =
from order in context.SalesOrderHeaders
where order.OrderDate >= new DateTime(2003, 12, 1)
select order;
Console.WriteLine("Orders that were made after December 1, 2003:");
foreach (SalesOrderHeader order in query)
{
Console.WriteLine($"OrderID {order.SalesOrderID} Order date: {order.OrderDate:d} ");
foreach (SalesOrderDetail orderDetail in order.SalesOrderDetails)
{
Console.WriteLine($" Product ID: {orderDetail.ProductID} Unit Price {orderDetail.UnitPrice}");
}
}
}
Using context As New AdventureWorksEntities
Dim orders As ObjectSet(Of SalesOrderHeader) = context.SalesOrderHeaders
Dim query = _
From order In orders _
Where order.OrderDate >= New DateTime(2003, 12, 1) _
Select order
Console.WriteLine("Orders that were made after December 1, 2003:")
For Each order In query
Console.WriteLine("OrderID {0} Order date: {1:d} ", _
order.SalesOrderID, order.OrderDate)
For Each orderDetail In order.SalesOrderDetails
Console.WriteLine(" Product ID: {0} Unit Price {1}", _
orderDetail.ProductID, orderDetail.UnitPrice)
Next
Next
End Using