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


Примеры синтаксиса выражения запроса: навигация по связям

Свойства навигации в Entity Framework — это свойства-ссылки, используемые для поиска сущностей в конечных точках ассоциации. Свойства навигации позволяют пользователю перемещаться из одной сущности в другую или из одной сущности в связанные сущности через набор ассоциаций. В этом разделе приведены примеры синтаксиса выражения запроса о том, как перемещаться по связям с помощью свойств навигации в запросах LINQ to Entity.

Модель продаж AdventureWorks, используемая в этих примерах, создается из таблиц Contact, Address, Product, SalesOrderHeader и SalesOrderDetail в примере базы данных AdventureWorks.

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

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

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 для поиска заказов, выполненных после 1 декабря 2003 года, а затем использует свойство навигации 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

См. также