导航属性

实体数据模型 中的导航属性是快捷方式属性,用于定位位于关联各端的实体。使用导航属性可以通过关联集从一个实体导航到另一个实体,或从一个实体导航到多个相关的实体。导航属性可用在 Entity SQL 查询和 LINQ to Entities 查询中。通过这些属性,无需执行 JOIN 操作就可访问相关实体。有关更多信息,请参见导航属性 (EDM)

下面采用基于方法的查询语法的示例使用 SelectMany 方法获取其姓氏为“Zhou”的联系人的所有订单。Contact.SalesOrderHeader 导航属性用于获取每个联系人的 SalesOrderHeader 对象的集合。

Using AWEntities As New AdventureWorksEntities
    Dim ordersQuery = AWEntities.Contact _
    .Where(Function(c) c.LastName = "Zhou") _
    .SelectMany(Function(o) o.SalesOrderHeader)

    For Each order In ordersQuery
        Console.WriteLine("Order ID: {0}, Order date: {1}, Total Due: {2}", _
                order.SalesOrderID, order.OrderDate, order.TotalDue)
    Next
End Using
using (AdventureWorksEntities AWEntities = new AdventureWorksEntities())
{
    IQueryable<SalesOrderHeader> ordersQuery = AWEntities.Contact
        .Where(c => c.LastName == "Zhou")
        .SelectMany(c => c.SalesOrderHeader);

    foreach (var order in ordersQuery)
    {
        Console.WriteLine("Order ID: {0}, Order date: {1}, Total Due: {2}",
            order.SalesOrderID, order.OrderDate, order.TotalDue);
    }
}

导航属性还出现在 CLR 中实体的实例中,您可以通过调用 Load 方法来加载相关实体。加载 CLR 中的实体时,应在访问该实体的成员之前显式加载导航属性。加载这些属性可避免在数据源之间进行意外往返。但是,由于 LINQ to Entities 查询是在数据源中进行计算的,因此不需要额外的往返,导航属性用作更复杂的导航表达式的占位符。

如果在连接字符串中设置 MultipleActiveResultSets=True,可以在 foreach/For Each 循环内显式加载导航属性。如果连接字符串包含 MultipleActiveResultSets=False,则下面示例中的 Load 方法调用将引发 EntityCommandExecutionException

Using AWEntities As New AdventureWorksEntities()
    Dim contacts = _
        AWEntities.Contact _
        .Where(Function(c) c.LastName = "Johnson") _
        .Select(Function(c) c)

    Try
        For Each contact As Contact In contacts

            Console.WriteLine("Name: {0}, {1}", contact.LastName, contact.FirstName)

            ' Throws a EntityCommandExecutionException if 
            ' MultipleActiveResultSets is set to False in the 
            ' connection string.
            contact.SalesOrderHeader.Load()

            For Each order As SalesOrderHeader In contact.SalesOrderHeader
                Console.WriteLine("Order ID: {0}", order.SalesOrderID)
            Next

        Next
    Catch ex As EntityCommandExecutionException

        Console.WriteLine(ex.InnerException)
    End Try
End Using
using (AdventureWorksEntities AWEntities = new AdventureWorksEntities())
{
    IQueryable<Contact> contacts =
            AWEntities.Contact
            .Where(c => c.LastName == "Johnson")
            .Select(c => c);

    try
    {

        foreach (Contact contact in contacts)
        {
            Console.WriteLine("Name: {0}, {1}", contact.LastName, contact.FirstName);
            
            // Throws a EntityCommandExecutionException if 
            // MultipleActiveResultSets is set to False in the 
            // connection string.
            contact.SalesOrderHeader.Load();

            foreach (SalesOrderHeader order in contact.SalesOrderHeader)
            {
                Console.WriteLine("Order ID: {0}", order.SalesOrderID);
            }
        }
    }
    catch (EntityCommandExecutionException ex)
    {
        Console.WriteLine(ex.InnerException);
    }
}

另请参见

概念

基于方法的查询语法示例:导航关系 (LINQ to Entities)
LINQ to Entities 查询中的表达式