Partilhar via


Consultando entre relacionamentos

As referências a outros objetos ou coleções de outros objetos em suas definições de classe correspondem diretamente a relações de chave estrangeira no banco de dados. Você pode usar essas relações ao consultar usando a notação de pontos para acessar as propriedades da relação e navegar de um objeto para outro. Essas operações de acesso se traduzem em junções mais complexas ou subconsultas correlacionadas no SQL equivalente.

Por exemplo, a consulta a seguir navega de pedidos para clientes como uma forma de restringir os resultados apenas aos pedidos de clientes localizados em Londres.

        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

Se as propriedades de relacionamento não existissem, você teria que escrevê-las manualmente como junções, assim como faria em uma consulta SQL, como no código a seguir:

        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

Você pode usar a propriedade relationship para definir essa relação específica uma vez. Em seguida, você pode usar a sintaxe de pontos mais conveniente. Mas as propriedades de relacionamento existem mais importante porque os modelos de objeto específicos do domínio são normalmente definidos como hierarquias ou gráficos. Os objetos que você programa contra têm referências a outros objetos. É apenas uma feliz coincidência que as relações objeto-a-objeto correspondam a relações de estilo de chave estrangeira em bancos de dados. O acesso à propriedade fornece uma maneira conveniente de escrever junções.

Com relação a isso, as propriedades de relacionamento são mais importantes no lado dos resultados de uma consulta do que como parte da própria consulta. Depois que a consulta tiver recuperado dados sobre um cliente específico, a definição de classe indica que os clientes têm pedidos. Em outras palavras, você espera que a Orders propriedade de um determinado cliente seja uma coleção que é preenchida com todos os pedidos desse cliente. Esse é, de facto, o contrato que declarou ao definir as classes desta forma. Você espera ver os pedidos lá, mesmo que a consulta não solicite pedidos. Você espera que seu modelo de objeto mantenha uma ilusão de que é uma extensão na memória do banco de dados com objetos relacionados imediatamente disponíveis.

Agora que você tem relações, pode escrever consultas consultando as propriedades de relacionamento definidas em suas classes. Essas referências de relacionamento correspondem a relações de chave estrangeira no banco de dados. As operações que usam essas relações se traduzem em junções mais complexas no SQL equivalente. Contanto que você tenha definido um relacionamento (usando o AssociationAttribute atributo), não é necessário codificar uma junção explícita no LINQ to SQL.

Para ajudar a manter essa ilusão, o LINQ to SQL implementa uma técnica chamada carregamento diferido. Para obter mais informações, consulte Carregamento adiado versus imediato.

Considere a seguinte consulta SQL para projetar uma lista de CustomerID-OrderID pares:

SELECT t0.CustomerID, t1.OrderID  
FROM   Customers AS t0 INNER JOIN  
          Orders AS t1 ON t0.CustomerID = t1.CustomerID  
WHERE  (t0.City = @p0)  

Para obter os mesmos resultados usando LINQ to SQL, use a referência de Orders propriedade já existente na Customer classe. A Orders referência fornece as informações necessárias para executar a consulta e projetar os CustomerID-OrderID pares, como no código a seguir:

        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

Você também pode fazer o inverso. Ou seja, você pode consultar Orders e usar sua Customer referência de relacionamento para acessar informações sobre o objeto associado Customer . O código a seguir projeta os mesmos CustomerID-OrderID pares que antes, mas desta vez consultando Orders em vez de .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

Consulte também