Vous avez raison, mais la règle est plus complexe à faire fonctionner vraiment comme prévu. Si vous définissez votre propriété de navigation virtual
EF à l'exécution de créer une nouvelle classe (dynamic proxy) provenant de votre Brand
de la classe et de l'utiliser à la place. Ce nouveau créé dynamiquement classe contient la logique de charger une propriété de navigation lorsque vous accédez pour la première fois. Cette fonction est appelée au chargement différé (ou mieux transparente lazy loading).
Quelles règles doivent être rencontrer pour faire ce travail:
- Toutes les propriétés de navigation dans la classe doit être
virtual
- Dynamique de la création de proxy ne doit pas être désactivé (
context.Configuration.ProxyCreationEnabled
). Il est activé par défaut.
- Chargement différé ne doit pas être désactivé (
context.Configuration.LazyLoadingEnabled
). Il est activé par défaut.
- L'entité doit être jointe (par défaut si vous chargez de l'entité de la base de données) pour le contexte et le contexte ne doit pas être éliminé = chargement paresseux ne fonctionne que dans la portée de contexte de vie utilisé pour le charger à partir de la base de données (ou proxy entité a été jointe)
À l'opposé de lazy loading est appelé impatient de chargement et c'est ce qu' Include
n'. Si vous utilisez Include
votre propriété de navigation est chargé avec de l'entité.
L'utilisation de chargement paresseux et désireux de chargement dépend de vos besoins et également sur les performances. Include
charge toutes les données dans une seule requête de base de données, mais il peut entraîner un vaste ensemble de données lors de l'utilisation de beaucoup de ou le chargement d'un grand nombre d'objets. Si vous êtes sûr que vous aurez besoin d' Brand
et tous Products
pour le traitement, vous devez utiliser désireux de chargement.
Lazy loading est à son tour utilisé si vous n'êtes pas sûr de la propriété de navigation dont vous aurez besoin. Par exemple, si vous chargez 100 marques, mais vous aurez besoin d'accéder uniquement à des produits d'une marque, il n'est pas nécessaire de charger des produits pour toutes les marques dans la requête initiale. L'inconvénient de le lazy loading est séparé de requête de données (aller-retour) pour chaque propriété de navigation => si vous chargez 100 marques sans inclure et vous pourrez accéder Products
propriété dans chaque Brand
exemple votre code va générer un autre 100 requêtes pour remplir ces propriétés de navigation = désireux de chargement utiliserait qu'simple requête, mais le chargement paresseux utilisé 101 requêtes (il est appelé N + 1 problème).
Dans des scénarios plus complexes, vous pouvez trouver qu'aucune de ces stratégies fonctionnent comme vous le souhaitez et vous pouvez utiliser soit le troisième stratégie explicite de chargement ou de séparer les requêtes de la charge de marques et de produits pour toutes les marques dont vous avez besoin.
Le chargement explicite a les mêmes inconvénients que le chargement paresseux, mais vous devez déclencher manuellement:
context.Entry(brand).Collection(b => b.Products).Load();
Les principaux avantages pour le chargement explicite est la capacité de filtre de rapport. Vous pouvez utiliser Query()
avant Load()
et l'utilisation de tout filtrage ou même désireux de chargement de relations imbriquées.