En el siguiente blog: http://weblogs.asp.net/scottgu/archive/2010/07/16/code-first-development-with-entity-framework-4.aspx
El blog contiene el siguiente ejemplo de código:
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; }
}
¿Cuál es el propósito de usar virtual
al definir una propiedad en una clase? ¿Qué efecto tiene?
c#
class
properties
virtual
Gary Jones
fuente
fuente
Respuestas:
Permite que Entity Framework cree un proxy alrededor de la propiedad virtual para que la propiedad pueda soportar una carga diferida y un seguimiento de cambios más eficiente. Consulte ¿Qué efecto (s) puede tener la palabra clave virtual en Entity Framework 4.1 POCO Code First? para una discusión más completa
Editar para aclarar "crear un proxy alrededor": por "crear un proxy alrededor" me refiero específicamente a lo que hace el Entity Framework. Entity Framework requiere que sus propiedades de navegación se marquen como virtuales para que se admitan cargas lentas y un seguimiento de cambios eficiente. Consulte los requisitos para crear proxies POCO .
Entity Framework utiliza la herencia para admitir esta funcionalidad, por lo que requiere que ciertas propiedades se marquen virtuales en sus POCO de clase base. Literalmente crea nuevos tipos que se derivan de sus tipos de POCO. Por lo tanto, su POCO actúa como un tipo base para las subclases creadas dinámicamente de Entity Framework. Eso es lo que quise decir con "crear un proxy alrededor".
Las subclases creadas dinámicamente que Entity Framework crea se hacen evidentes cuando se usa Entity Framework en tiempo de ejecución, no en tiempo de compilación estático. Y solo si habilita las funciones de carga diferida de Entity Framework o de seguimiento de cambios. Si opta por no utilizar nunca las funciones de carga diferida o de seguimiento de cambios de Entity Framework (que no es la predeterminada), no necesita declarar ninguna de sus propiedades de navegación como virtuales. Luego, usted es responsable de cargar esas propiedades de navegación usted mismo, ya sea utilizando lo que Entity Framework denomina "carga ansiosa" o recuperando manualmente los tipos relacionados en múltiples consultas de bases de datos. Sin embargo, puede y debe usar funciones de carga diferida y seguimiento de cambios para sus propiedades de navegación en muchos escenarios.
Si crea una clase independiente y marca propiedades como virtuales, y simplemente construye y usa instancias de esas clases en su propia aplicación, completamente fuera del alcance de Entity Framework, entonces sus propiedades virtuales no le darían nada en su propio.
Edite para describir por qué las propiedades se marcarían como virtuales
Propiedades como:
No son campos y no deben considerarse como tales. Estos se llaman getters y setters y en el momento de la compilación, se convierten en métodos.
Es por eso que están marcados como virtuales para su uso en Entity Framework, permite que las clases creadas dinámicamente anulen las funciones
get
y lasset
funciones generadas internamente . Si sus captadores / establecedores de propiedades de navegación están trabajando para usted en el uso de Entity Framework, intente revisarlos solo para propiedades, recompilar y ver si Entity Framework todavía puede funcionar correctamente:fuente
La
virtual
palabra clave en C # permite que las clases secundarias anulen un método o una propiedad. Para obtener más información, consulte la documentación de MSDN sobre la palabra clave "virtual"ACTUALIZACIÓN: Esto no responde la pregunta como se hace actualmente, pero la dejaré aquí para cualquiera que busque una respuesta simple a la pregunta original no descriptiva que se hizo.
fuente
virtual
propiedades a través de Entity Framework, aunque no es explícito en el título de OP. La respuesta aceptada es así porque toca el lado de Entity Framework de las cosas y cómo / por quévirtual
se usan las propiedades en ese contexto.Entiendo la frustración de los OP, este uso de virtual no es para la abstracción con plantilla para la que el modificador virtual de facto es efectivo.
Si alguno todavía está luchando con esto, ofrecería mi punto de vista, ya que trato de mantener las soluciones simples y la jerga al mínimo:
Entity Framework en una pieza simple utiliza carga diferida, que es el equivalente de preparar algo para la ejecución futura. Eso se ajusta al modificador 'virtual', pero hay más en esto.
En Entity Framework, el uso de una propiedad de navegación virtual le permite denotarlo como el equivalente de una Clave externa anulable en SQL. No tiene que unirse con entusiasmo a todas las tablas con clave cuando realiza una consulta, pero cuando necesita la información, se vuelve impulsada por la demanda.
También mencioné anulable porque muchas propiedades de navegación no son relevantes al principio. es decir, en un escenario de cliente / pedidos, no tiene que esperar hasta el momento en que se procesa un pedido para crear un cliente. Se puede, pero si tuviera un proceso de varias etapas para lograr esto, es posible encontrar la necesidad de persistir los datos de los clientes para la finalización de plazo o para su implementación en futuros pedidos. Si se implementaran todas las propiedades de navegación, tendría que establecer cada clave externa y campo relacional en el guardado. Eso realmente solo restablece los datos en la memoria, lo que anula el papel de la persistencia.
Entonces, aunque puede parecer críptico en la ejecución real en tiempo de ejecución, he encontrado que la mejor regla general para usar sería: si está generando datos (leyendo en un Modelo de visualización o Modelo serializable) y necesita valores antes de las referencias, no usar virtual; Si su alcance es la recopilación de datos que pueden estar incompletos o la necesidad de buscar y no requieren que todos los parámetros de búsqueda se completen para una búsqueda, el código hará un buen uso de la referencia, de manera similar al uso de las propiedades de valor anulables int? ¿largo?. Además, abstraer su lógica de negocios de su recopilación de datos hasta la necesidad de inyectarla tiene muchos beneficios de rendimiento, similar a crear instancias de un objeto y comenzarlo desde cero. Entity Framework utiliza mucha reflexión y dinámica, lo que puede degradar el rendimiento, y la necesidad de tener un modelo flexible que se pueda adaptar a la demanda es fundamental para gestionar el rendimiento.
Para mí, eso siempre tuvo más sentido que usar jerga tecnológica sobrecargada como representantes, delegados, controladores y demás. Una vez que llegas a tu tercera o cuarta programación lang, puede ser complicado con estos.
fuente
Del libro "ASP.NET MVC 5 con Bootstrap y Knockout.js"
fuente
En el contexto de EF, marcar una propiedad como virtual le permite a EF usar carga diferida para cargarla. Para que la carga diferida funcione, EF tiene que crear un objeto proxy que anule sus propiedades virtuales con una implementación que carga la entidad referenciada cuando se accede por primera vez. Si no marca la propiedad como virtual, la carga diferida no funcionará con ella.
fuente
La palabra clave virtual se usa para modificar un método, propiedad, indexador o declaración de evento y permitir que se anule en una clase derivada. Por ejemplo, este método puede ser anulado por cualquier clase que lo herede:
fuente
No podemos hablar de miembros virtuales sin referirnos al polimorfismo . De hecho, una función, propiedad, indexador o evento en una clase base marcada como virtual permitirá la anulación de una clase derivada.
Por defecto, los miembros de una clase no son virtuales y no se pueden marcar como si fueran modificadores estáticos, abstractos, privados o de anulación.
Ejemplo Consideremos el método ToString () en System.Object . Debido a que este método es miembro de System.Object, se hereda en todas las clases y proporcionará los métodos ToString () a todos ellos.
La salida del código anterior es:
Consideremos que queremos cambiar el comportamiento estándar de los métodos ToString () heredados de System.Object en nuestra clase Company. Para lograr este objetivo, es suficiente usar la palabra clave de anulación para declarar otra implementación de ese método.
Ahora, cuando se invoca un método virtual, el tiempo de ejecución verificará si hay un miembro superior en su clase derivada y lo llamará si está presente. El resultado de nuestra aplicación será:
De hecho, si marca la clase System.Object, encontrará que el método está marcado como virtual.
fuente