Прочитать на английском

Поделиться через


Свойства навигации

Свойства навигации в модели Entity Data Model — это свойства быстрого доступа, используемые для нахождения сущностей в окончаниях ассоциации. Свойства навигации позволяют переходить от одной сущности к другой или от сущности к связанным сущностям в наборе ассоциаций. Свойства навигации можно использовать в запросах 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 выполняются в источнике данных, необходимость в дополнительных циклах не возникает и свойство выступает в качестве местозаполнителя для более сложного выражения навигации.

Можно явно загрузить свойства навигации в цикле foreach/For Each, если в строке соединения задано значение MultipleActiveResultSets=True. Если строка соединения содержит значение 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