Выполнение запросов в связяхQuerying Across Relationships

Ссылки на другие объекты или коллекции других объектов в определениях классов указывают непосредственно на связи внешнего ключа в базе данных.References to other objects or collections of other objects in your class definitions directly correspond to foreign-key relationships in the database. Эти связи можно использовать при осуществлении запроса с помощью точечной нотации для доступа к свойствам связей и перехода от одного объекта к другому.You can use these relationships when you query by using dot notation to access the relationship properties and navigate from one object to another. Эти операции доступа преобразуются в более сложные соединения или коррелированные подзапросы в эквивалентном SQL.These access operations translate to more complex joins or correlated subqueries in the equivalent SQL.

Например, следующий запрос переходит от заказов к клиентам в качестве способа ограничения результатов только заказами для клиентов, находящихся в Лондоне.For example, the following query navigates from orders to customers as a way to restrict the results to only those orders for customers located in London.

        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-запросе, как показано в следующем коде:If relationship properties did not exist you would have to write them manually as joins, just as you would do in a SQL query, as in the following code:

        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

Можно использовать свойство Relationship , чтобы определить эту конкретную связь один раз.You can use the relationship property to define this particular relationship one time. После этого можно применять более удобный точечный синтаксис.You can then use the more convenient dot syntax. Однако существование свойств связи более важно, поскольку объектные модели, характерные для доменов, обычно определяются как иерархии или графики.But relationship properties exist more importantly because domain-specific object models are typically defined as hierarchies or graphs. Программируемые объекты имеют ссылки на другие объекты.The objects that you program against have references to other objects. Соответствие связей "объект-объект" связям внешнего ключа в базах данных является лишь совпадением.It is only a happy coincidence that object-to-object relationships correspond to foreign-key-styled relationships in databases. Доступ к свойству предоставляет удобный способ для написания соединений.Property access then provides a convenient way to write joins.

В связи с этим свойства связи являются более важными как результаты запроса, чем как часть самого запроса.With regard to this, relationship properties are more important on the results side of a query than as part of the query itself. После того, как запрос извлечет, данные о конкретном клиенте, определение класса указывает наличие заказов.After the query has retrieved data about a particular customer, the class definition indicates that customers have orders. Другими словами, ожидается, что свойство Orders конкретного клиента является коллекцией, заполняемой всеми заказами данного клиента.In other words, you expect the Orders property of a particular customer to be a collection that is populated with all the orders from that customer. На самом деле это контракт, объявленный путем подобного определения классов.That is in fact the contract you declared by defining the classes in this manner. Вы хотите увидеть в нем заказы, даже если они не требуются для запроса.You expect to see the orders there even if the query did not request orders. Вы хотите, чтобы объектная модель поддерживала представление о том, что это находящееся в памяти расширение базы данных со связанными и немедленно доступными объектами.You expect your object model to maintain an illusion that it is an in-memory extension of the database with related objects immediately available.

Теперь при наличии связей можно писать запросы, обращаясь к свойствам связей, определенным в классах.Now that you have relationships, you can write queries by referring to the relationship properties defined in your classes. Эти ссылки на связи соответствуют связям внешнего ключа в базе данных.These relationship references correspond to foreign-key relationships in the database. Операции, использующие эти связи, преобразуются в более сложные соединения в эквивалентном SQL.Operations that use these relationships translate to more complex joins in the equivalent SQL. После определения связи (с помощью атрибута AssociationAttribute) не требуется кодировать явное соединение в LINQ to SQLLINQ to SQL.As long as you have defined a relationship (using the AssociationAttribute attribute), you do not have to code an explicit join in LINQ to SQLLINQ to SQL.

Для поддержки этой иллюзии LINQ to SQLLINQ to SQL реализует метод, называемый отложенной загрузкой.To help maintain this illusion, LINQ to SQLLINQ to SQL implements a technique called deferred loading. Дополнительные сведения см. в разделе Отложенная и немедленная загрузка.For more information, see Deferred versus Immediate Loading.

Рассмотрим следующий SQL-запрос для проецирования списка CustomerID-OrderID пар:Consider the following SQL query to project a list of CustomerID-OrderID pairs:

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 SQLLINQ to SQL, используйте ссылку на свойство Orders, уже существующую в классе Customer.To obtain the same results by using LINQ to SQLLINQ to SQL, you use the Orders property reference already existing in the Customer class. Ссылка на Orders предоставляет необходимые сведения для выполнения запроса и проецирования CustomerID-OrderID пар, как показано в следующем коде:The Orders reference provides the necessary information to execute the query and project the CustomerID-OrderID pairs, as in the following code:

        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

Также можно выполнить обратное.You can also do the reverse. Это значит, что можно запросить Orders и использовать ссылку на связь Customer для получения сведений о связанном объекте Customer.That is, you can query Orders and use its Customer relationship reference to access information about the associated Customer object. Следующий код проецирует то же CustomerID-OrderID, как и раньше, но на этот раз путем запроса Orders вместо Customers.The following code projects the same CustomerID-OrderID pairs as before, but this time by querying Orders instead of 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

См. также:See also