52 votes

Propriétés virtuelles Entity Framework 4.1

Si j'ai déclaré entité-relation dans mon modèle virtuel, il n'est pas nécessaire d'utiliser l' Include déclaration dans ma requête LINQ, non ??-

Ex: C'est mon modèle de classe :

public class Brand
{
    public int BrandID { get; set; }
    public string BrandName { get; set; }
    public string BrandDesc { get; set; }
    public string BrandUrl { get; set; }

    public virtual ICollection<Product> Products { get; set; }
}

Maintenant, pour le modèle ci-dessus classe, je n'ai pas besoin d'utiliser l' var barndsAndProduct = pe.Brands.Include("Products").Single(brand => brand.BrandID == 22); .

Au lieu de cela, je peux utiliser le simple var barndsAndProduct = pe.Brands.Where(brand => brand.BrandID == 22); et j'ai automatiquement l'entité liée disponibles lors de l'accès.

Ai-je raison de ma compréhension ?

Aussi, veuillez me dire dans quelles situations je préférerais l'un sur l'autre ??

165voto

Ladislav Mrnka Points 218632

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.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X