Quel (s) effet (s) le mot-clé virtuel peut-il avoir dans Entity Framework 4.1 POCO Code First?

229

Le virtualmot - clé a- t -il un effet lorsqu'il est utilisé sur les propriétés dans EF Code First?. Quelqu'un peut-il décrire toutes ses ramifications dans différentes situations?

Par exemple, je sais qu'il peut contrôler le chargement différé - si vous utilisez le mot-clé virtuel sur une propriété de relation ICollection / un-à-plusieurs, il sera chargé par défaut par défaut, tandis que si vous laissez le mot-clé virtuel hors, il être impatient.

Quels autres effets un virtualmot-clé peut -il avoir dans EF avec des entités POCO?. Dois-je le rendre par défaut à utiliser virtualsur toutes mes propriétés, ou par défaut à ne pas l'utiliser?

Scott Stafford
la source

Réponses:

194

Jusqu'à présent, je connais ces effets.

  • Chargement différé : toutes les virtualICollections seront chargées paresseusement, sauf indication contraire.
  • Suivi des modifications plus efficace . Si vous remplissez toutes les conditions suivantes, votre suivi des modifications peut utiliser une méthode plus efficace en accrochant vos propriétés virtuelles. Depuis le lien:

    Pour obtenir des proxys de suivi des modifications, la règle de base est que votre classe doit être publique, non abstraite ou non scellée. Votre classe doit également implémenter des getters / setters virtuels publics pour toutes les propriétés persistantes. Enfin, vous devez déclarer les propriétés de navigation des relations basées sur la collection ICollection<T>uniquement. Ils ne peuvent pas être une implémentation concrète ou une autre interface qui dérive de ICollection<T>(une différence par rapport au proxy de chargement différé)

Un autre lien utile décrivant cela est les exigences de MSDN pour la création de proxys POCO .

Scott Stafford
la source
52
Il n'y a aucune autre raison pour rendre les propriétés virtuelles. Les propriétés de navigation sont marquées comme virtuelles pour le chargement paresseux et les propriétés scalaires sont marquées comme virtuelles pour le suivi des modifications.
Ladislav Mrnka
10
quelles sont les propriétés de navigation et quelles sont les propriétés scalaires?
Abid Ali
9
@AbidAli: Je crois qu'une propriété de navigation est une clé étrangère (un type de classe d'entité) ou une relation un à plusieurs (de type ICollection <>). Une propriété scalaire est un type de base (int, chaîne, ..) ou un ComplexType (qui n'est qu'une structure de types de base).
Scott Stafford du
2
" public virtual byte[] bigData { get; set; }" Le chargement est-il paresseux?
AechoLiu
9
octets [] seront chargés avec impatience, seules les clés étrangères peuvent être paresseuses. Si vous ne voulez pas récupérer cette colonne, ne récupérez jamais l'enregistrement entier - juste .Select(a=>new { fields you want }).
Scott Stafford
63

Ce mot-clé virtuel est lié au thème du chargement des données à partir du framework d'entité (chargement paresseux, chargement rapide et chargement explicite).

Vous devez utiliser un mot-clé virtuel lorsque vous souhaitez charger des données avec un chargement paresseux.

le chargement différé est le processus par lequel une entité ou une collection d'entités est automatiquement chargée à partir de la base de données lors du premier accès.

Par exemple, lors de l'utilisation de la classe d'entité Blog définie ci-dessous, les publications associées seront chargées lors du premier accès à la propriété de navigation Posts:

public class Blog 
{  
     public int BlogId { get; set; }  
     public string Name { get; set; }  
     public string Url { get; set; }  
     public string Tags { get; set; }  
     public virtual ICollection<Post> Posts { get; set; }  
}

Le chargement paresseux de la collection Posts peut être désactivé en rendant la propriété Posts non virtuelle.

si le chargement différé est désactivé, le chargement de la collection Posts peut toujours être réalisé en utilisant un chargement rapide (en utilisant la méthode Include) ou en chargeant explicitement des entités liées (en utilisant la méthode Load).

Chargement ardent:

using (var context = new BloggingContext()) 
{ 
    // Load all blogs and related posts 
    var blogs1 = context.Blogs 
                          .Include(b => b.Posts) 
                          .ToList(); 
}

Chargement explicite:

using (var context = new BloggingContext()) 
{ 
    var blog = context.Blogs.Find(1); 

    // Load the posts related to a given blog 
    context.Entry(blog).Collection(p => p.Posts).Load(); 
}
Parsa
la source
1
Comment éviter le problème N + 1 lors de l'utilisation de virtual (chargement différé)? Par exemple, context.Blogs.ToList (); il ne rejoindra pas les tables et exécutera la requête de sélection autant que le nombre de blogs.
expert veut être le
1
@Expertwannabe Même si vous utilisez le chargement différé, vous pouvez toujours demander explicitement un chargement rapide avec un appel à Include().
Mgr