Partager via


Interrogation de relations

Les références à d’autres objets ou collections d’autres objets dans vos définitions de classe correspondent directement à des relations de clé étrangère dans la base de données. Vous pouvez utiliser ces relations lorsque vous effectuez une interrogation avec la notation par point pour accéder aux propriétés de relation et naviguer entre les objets. Ces opérations d'accès sont traduites en jointures complexes ou en sous-requêtes corrélées plus complexes dans le SQL équivalent.

Par exemple, la requête suivante navigue des commandes aux clients afin de limiter les résultats aux commandes des clients localisés à 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

Si les propriétés de relation n’existaient pas, vous devriez les écrire manuellement sous forme de jointures, comme vous le feriez dans une requête SQL, par exemple dans le code suivant :

        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

Vous pouvez utiliser la propriété relationship pour définir une seule fois cette relation spécifique. Vous pouvez ensuite utiliser la syntaxe à point qui est plus pratique. Toutefois, les propriétés de relation sont plus importantes en raison du fait que les modèles objet spécifiques au domaine sont généralement définis comme des hiérarchies ou des graphiques. Les objets par rapport auxquels vous effectuez la programmation ont des références à d'autres objets. C'est une simple coïncidence que les relations entre objets correspondent aux relations de clé étrangère dans les bases de données. L'accès aux propriétés permet ensuite d'écrire facilement des jointures.

À cet égard, les propriétés de relation sont plus importantes du point de vue des résultats d'une requête que de la requête elle-même. Une fois que la requête a récupéré des données concernant un client spécifique, la définition de classe indique que les clients ont des commandes. En d'autres termes, la propriété Orders d'un client spécifique doit être une collection comportant toutes les commandes de ce client. Il s'agit en fait du contrat que vous avez déclaré en définissant les classes de cette manière. Vous vous attendez à voir apparaître les commandes même si la requête ne les a pas demandées. Vous souhaitez que votre modèle objet continue de donner l'impression qu'il s'agit d'une extension en mémoire de la base de données avec les objets connexes immédiatement disponibles.

Maintenant que vous disposez de relations, vous pouvez écrire des requêtes en faisant référence aux propriétés de relation définies dans vos classes. Ces références de relation correspondent aux relations de clé étrangère dans la base de données. Les opérations qui utilisent ces relations sont traduites en jointures plus complexes dans le SQL équivalent. Dès lors que vous avez défini une relation (en utilisant l’attribut AssociationAttribute), vous n’avez pas besoin de coder une jointure explicite dans LINQ to SQL.

Pour maintenir cette illusion, LINQ to SQL implémente une technique appelée chargement différé. Pour plus d’informations, consultez Comparaison entre le chargement différé et le chargement immédiat.

Considérez la requête SQL suivante pour projeter une liste de paires CustomerID-OrderID :

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

Pour obtenir les mêmes résultats en utilisant LINQ to SQL, vous utilisez la référence de propriété Orders qui existe déjà dans la classe Customer. La référence Orders fournit les informations nécessaires pour exécuter la requête et projeter les paires CustomerID-OrderID, comme dans le code suivant :

        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

Vous pouvez également effectuer l'opération inverse. Vous pouvez en effet interroger Orders et utiliser sa référence de relation Customer pour accéder aux informations sur l'objet Customer associé. Le code suivant projette les mêmes paires CustomerID-OrderID que précédemment, mais cette fois en interrogeant Orders au lieu 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

Voir aussi