web-dev-qa-db-fra.com

Comment construire une requête LINQ to Entities pour charger directement des objets enfants, au lieu d'appeler une propriété Reference ou Load ()

Je suis nouveau dans l'utilisation de LINQ to Entities (ou Entity Framework, peu importe comment ils l'appellent) et j'écris beaucoup de code comme ceci:

var item = (from InventoryItem item in db.Inventory
            where item.ID == id
            select item).First<InventoryItem>();

puis appeler des méthodes sur cet objet comme ceci:

var type = item.ItemTypeReference;

ou

var orders = item.OrderLineItems.Load();

pour récupérer un enfant ou des objets associés.

Je n'ai pas profilé la base de données ou creusé trop profondément, mais je suppose que lorsque j'appelle une propriété .Load () ou * Reference, je fais en fait un autre appel à la base de données. Si tel est le cas, existe-t-il un moyen d'obtenir ces objets dans mon expression LINQ initiale?

42
JC Grubbs

Vous souhaitez utiliser les références de méthode .Include (string) dans cet article "Shaping query results" .

var item = from InventoryItem item in
              db.Inventory.Include("ItemTypeReference").Include("OrderLineItems")
           where item.ID == id
           select item;

Il existe probablement aussi une syntaxe de style "sql" pour les inclus.

Voir également cette article sur le passage de LINQ-to-SQL à LINQ-to-Entities.

Pour ceux qui recherchent une solution à ce problème pour Linq to SQL , vous souhaitez effectuer les opérations suivantes (Substitute DataContext et autres types pour tout ce que vous avez):

using (DataContext db = new DataContext())
{
    DataLoadOptions options = new DataLoadOptions();
    options.LoadWith<InventoryItem>(ii => ii.ItemTypeReference);
    options.LoadWith<InventoryItem>(ii => ii.OrderLineItems);
    db.LoadOptions = options;

    var item = from InventoryItem item in db.Inventory
               where item.ID == id
               select item;
}

Cela chargera les propriétés spécifiées dans LoadWith chaque fois que l'élément parent (InventoryItem) est chargé, pour ce contexte particulier.

En réponse à d'autres questions de James et Jesper, consultez ceci question

62
Robert Wagner

En plus de la réponse de Robert, vous voudrez peut-être consulter cette question pour les options d'une méthode d'extension qui vous permet de .Include () en utilisant une expression au lieu d'une chaîne, de sorte que vous obtenez la vérification de l'heure de compilation:

Entity Framework .Include () avec vérification du temps de compilation?

0
Mike Chamberlain

AFAIK, Pour silverlight (services de domaine), ajouter l'attribut [Inclure] au bon endroit (sur la propriété de navigation dans les métadonnées) suffit https://stackoverflow.com/a/5332188/413032

0
Davut Gürbüz