Dans le blog suivant: http://weblogs.asp.net/scottgu/archive/2010/07/16/code-first-development-with-entity-framework-4.aspx
Le blog contient l'exemple de code suivant:
public class Dinner
{
public int DinnerID { get; set; }
public string Title { get; set; }
public DateTime EventDate { get; set; }
public string Address { get; set; }
public string HostedBy { get; set; }
public virtual ICollection<RSVP> RSVPs { get; set; }
}
public class RSVP
{
public int RsvpID { get; set; }
public int DinnerID { get; set; }
public string AttendeeEmail { get; set; }
public virtual Dinner Dinner { get; set; }
}
Quel est le but de l'utilisation virtual
lors de la définition d'une propriété dans une classe? Quel effet cela a-t-il?
c#
class
properties
virtual
Gary Jones
la source
la source
Réponses:
Il permet à Entity Framework de créer un proxy autour de la propriété virtuelle afin que la propriété puisse prendre en charge le chargement différé et un suivi des modifications plus efficace. Voir Quel (s) effet (s) le mot-clé virtuel peut-il avoir dans Entity Framework 4.1 POCO Code First? pour une discussion plus approfondie.
Modifier pour clarifier "créer un proxy autour": Par "créer un proxy autour", je me réfère spécifiquement à ce que fait Entity Framework. Entity Framework nécessite que vos propriétés de navigation soient marquées comme virtuelles afin que le chargement paresseux et le suivi efficace des modifications soient pris en charge. Voir Exigences pour la création de proxys POCO .
Entity Framework utilise l'héritage pour prendre en charge cette fonctionnalité, c'est pourquoi il nécessite que certaines propriétés soient marquées virtuelles dans vos POCO de classe de base. Il crée littéralement de nouveaux types qui dérivent de vos types POCO. Votre POCO agit donc comme un type de base pour les sous-classes créées dynamiquement d'Entity Framework. C'est ce que je voulais dire par «créer un proxy autour».
Les sous-classes créées dynamiquement que Entity Framework crée deviennent évidentes lors de l'utilisation de Entity Framework au moment de l'exécution, et non au moment de la compilation statique. Et seulement si vous activez le chargement paresseux de l'Entity Framework ou les fonctionnalités de suivi des modifications. Si vous choisissez de ne jamais utiliser les fonctions de chargement différé ou de suivi des modifications de Entity Framework (qui n'est pas la valeur par défaut), vous n'avez pas besoin de déclarer l'une de vos propriétés de navigation comme virtuelle. Vous êtes ensuite responsable du chargement de ces propriétés de navigation vous-même, soit en utilisant ce que Entity Framework appelle le «chargement rapide», soit en récupérant manuellement les types associés dans plusieurs requêtes de base de données. Cependant, vous pouvez et devez utiliser les fonctionnalités de chargement paresseux et de suivi des modifications pour vos propriétés de navigation dans de nombreux scénarios.
Si vous deviez créer une classe autonome et marquer des propriétés comme virtuelles, et simplement construire et utiliser des instances de ces classes dans votre propre application, complètement en dehors de la portée d'Entity Framework, alors vos propriétés virtuelles ne vous apporteraient rien posséder.
Modifier pour décrire pourquoi les propriétés seraient marquées comme virtuelles
Des propriétés telles que:
Ne sont pas des domaines et ne doivent pas être considérés comme tels. Celles-ci sont appelées getters et setters et au moment de la compilation, elles sont converties en méthodes.
C'est pourquoi ils sont marqués comme virtuels pour une utilisation dans Entity Framework, cela permet aux classes créées dynamiquement de remplacer les fonctions
get
et lesset
fonctions générées en interne . Si votre getter / setters de propriétés de navigation fonctionne pour vous dans votre utilisation d'Entity Framework, essayez de les réviser en propriétés, recompilez-les et voyez si Entity Framework est toujours en mesure de fonctionner correctement:la source
Le
virtual
mot clé en C # permet à une méthode ou à une propriété d'être remplacée par des classes enfants. Pour plus d'informations, reportez-vous à la documentation MSDN sur le mot-clé «virtuel»MISE À JOUR: Cela ne répond pas à la question telle qu'elle est actuellement posée, mais je la laisserai ici pour quiconque cherche une réponse simple à la question d' origine non descriptive posée.
la source
virtual
propriétés via Entity Framework - même si ce n'est pas explicite dans le titre de OP. La réponse acceptée est ainsi car elle touche au côté Entity Framework des choses, et comment / pourquoi lesvirtual
propriétés sont utilisées dans ce contexte.Je comprends la frustration des OP, cette utilisation du virtuel n'est pas pour l'abstraction basée sur des modèles pour laquelle le modificateur virtuel de facto est efficace.
Si certains luttent toujours avec cela, je voudrais offrir mon point de vue, car j'essaie de garder les solutions simples et le jargon au minimum:
Entity Framework dans une pièce simple utilise le chargement paresseux, ce qui équivaut à préparer quelque chose pour une exécution future. Cela correspond au modificateur «virtuel», mais il y a plus à cela.
Dans Entity Framework, l'utilisation d'une propriété de navigation virtuelle vous permet de la désigner comme l'équivalent d'une clé étrangère nullable en SQL. Vous n'avez PAS à joindre avec impatience chaque table à clés lorsque vous effectuez une requête, mais lorsque vous avez besoin des informations, elles dépendent de la demande.
J'ai également mentionné nullable car de nombreuses propriétés de navigation ne sont pas pertinentes au premier abord. Par exemple, dans un scénario client / commandes, vous n'avez pas à attendre le moment où une commande est traitée pour créer un client. Vous pouvez, mais si vous aviez un processus en plusieurs étapes pour y parvenir, vous pourriez trouver la nécessité de conserver les données client pour une exécution ultérieure ou pour le déploiement sur des commandes futures. Si toutes les propriétés de navigation ont été implémentées, vous devez établir chaque clé étrangère et champ relationnel lors de la sauvegarde. Cela remet vraiment les données en mémoire, ce qui détruit le rôle de la persistance.
Donc, même si cela peut sembler cryptique dans l'exécution réelle au moment de l'exécution, j'ai trouvé que la meilleure règle empirique à utiliser serait: si vous générez des données (lecture dans un modèle de vue ou un modèle sérialisable) et que vous avez besoin de valeurs avant les références, ne le faites pas utiliser virtuel; Si votre portée recueille des données qui peuvent être incomplètes ou un besoin de recherche et ne nécessitent pas tous les paramètres de recherche complétés pour une recherche, le code fera bon usage de la référence, similaire à l'utilisation des propriétés de valeur nullable int? longue?. En outre, l'abstraction de votre logique métier de votre collecte de données jusqu'à la nécessité de l'injecter présente de nombreux avantages en termes de performances, similaires à l'instanciation d'un objet et son démarrage à null. Entity Framework utilise beaucoup de réflexion et de dynamique, ce qui peut dégrader les performances, et la nécessité d'avoir un modèle flexible pouvant s'adapter à la demande est essentielle à la gestion des performances.
Pour moi, cela avait toujours plus de sens que d'utiliser un jargon technologique surchargé comme les mandataires, les délégués, les gestionnaires et autres. Une fois que vous avez atteint votre troisième ou quatrième langue de programmation, cela peut devenir compliqué.
la source
Extrait du livre "ASP.NET MVC 5 avec Bootstrap et Knockout.js"
la source
Dans le contexte d'EF, le marquage d'une propriété comme virtuelle permet à EF d'utiliser le chargement différé pour la charger. Pour que le chargement paresseux fonctionne, EF doit créer un objet proxy qui remplace vos propriétés virtuelles avec une implémentation qui charge l'entité référencée lors de son premier accès. Si vous ne marquez pas la propriété comme virtuelle, le chargement paresseux ne fonctionnera pas avec.
la source
Le mot-clé virtuel est utilisé pour modifier une méthode, une propriété, un indexeur ou une déclaration d'événement et permettre son remplacement dans une classe dérivée. Par exemple, cette méthode peut être remplacée par n'importe quelle classe qui en hérite:
la source
Nous ne pouvons pas parler de membres virtuels sans faire référence au polymorphisme . En fait, une fonction, une propriété, un indexeur ou un événement dans une classe de base marquée comme virtuelle permettra le remplacement d'une classe dérivée.
Par défaut, les membres d'une classe ne sont pas virtuels et ne peuvent pas être marqués comme cela s'il s'agit de modificateurs statiques, abstraits, privés ou de substitution.
Exemple Considérons la méthode ToString () dans System.Object . Parce que cette méthode est membre de System.Object, elle est héritée dans toutes les classes et fournira les méthodes ToString () à toutes.
La sortie du code précédent est:
Considérons que nous voulons changer le comportement standard des méthodes ToString () héritées de System.Object dans notre classe Company. Pour atteindre cet objectif, il suffit d'utiliser le mot clé override pour déclarer une autre implémentation de cette méthode.
Désormais, lorsqu'une méthode virtuelle est invoquée, le moteur d'exécution recherche un membre prioritaire dans sa classe dérivée et l'appelle s'il est présent. Le résultat de notre application sera alors:
En fait, si vous vérifiez la classe System.Object, vous constaterez que la méthode est marquée comme virtuelle.
la source