variable usar sharp referencia propiedades propiedad porque navegacion method framework and c# class properties virtual

usar - virtual c# referencia



¿Por qué usar ''virtual'' para las propiedades de clase en las definiciones de modelo de Entity Framework? (5)

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?


Es bastante común definir propiedades de navegación en un modelo para que sea virtual. Cuando una propiedad de navegación se define como virtual, puede aprovechar ciertas funcionalidades de Entity Framework. El más común es la carga perezosa.

La carga perezosa es una buena característica de muchos ORM porque le permite acceder dinámicamente datos relacionados desde un modelo. No recuperará innecesariamente los datos relacionados hasta que realmente se acceda a ellos, lo que reduce la consulta inicial de los datos de la base de datos.

Del libro "ASP.NET MVC 5 with Bootstrap and Knockout.js"


En el contexto de EF, marcar una propiedad como virtual permite a EF utilizar la carga diferida para cargarla. Para que la carga diferida funcione, EF tiene que crear un objeto proxy que invalide 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.


Entiendo la frustración de los OP, este uso de virtual no es para la abstracción de plantilla para la cual es efectivo el modificador virtual de facto.

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 la carga diferida, que es el equivalente a preparar algo para la ejecución futura. Eso se ajusta al modificador ''virtual'', pero hay más de esto.

En Entity Framework, el uso de una propiedad de navegación virtual le permite denotarla como el equivalente de una clave foránea anulable en SQL. No TIENE QUE unirse con entusiasmo a todas las tablas con clave al realizar una consulta, pero cuando necesita la información, se convierte en una demanda.

También mencioné nullable porque muchas propiedades de navegación no son relevantes al principio. es decir, en un escenario de Clientes / Pedidos, no tiene que esperar hasta el momento en que se procesa un pedido para crear un cliente. Puede, pero si tuvo un proceso de múltiples etapas para lograr esto, podría encontrar la necesidad de conservar los datos del cliente para completarlos más tarde o para implementarlos en pedidos futuros. Si se implementaran todas las propiedades de navegación, tendría que establecer cada clave externa y campo relacional en el guardado. Eso realmente vuelve a poner los datos en la memoria, lo que elimina el papel de la persistencia.

Entonces, aunque pueda parecer críptico en la ejecución real en el tiempo de ejecución, he encontrado que la mejor regla de oro para usar sería: si está enviando datos (leyendo en un modelo de vista o modelo serializable) y necesita valores antes de las referencias, no lo haga. uso virtual Si su alcance está recopilando datos que pueden estar incompletos o si necesita buscar y no requiere que todos los parámetros de búsqueda hayan sido completados para una búsqueda, el código hará un buen uso de la referencia, de manera similar al uso de propiedades de valor anulable int? ¿largo?. Además, abstraer la lógica de su negocio de la recopilación de datos hasta que la necesidad de inyectarla tiene muchos beneficios de rendimiento, similares a la creación de instancias de un objeto y su inicio en nulo. Entity Framework utiliza mucha reflexión y dinámica, lo que puede degradar el rendimiento, y la necesidad de tener un modelo flexible que pueda escalar a la demanda es fundamental para la gestión del rendimiento.

Para mí, eso siempre tenía más sentido que usar una jerga tecnológica sobrecargada como proxies, delegados, manejadores y demás. Una vez que llegue a su tercera o cuarta programación, puede complicarse con esto.


La palabra clave virtual en C # permite que un método o propiedad sea reemplazado por clases secundarias. Para obtener más información, consulte la documentación de MSDN en la palabra clave ''virtual''

ACTUALIZACIÓN: Esto no responde a la pregunta tal como se hace actualmente, pero la dejaré aquí para cualquier persona que busque una respuesta simple a la pregunta original , no descriptiva.


Permite que Entity Framework cree un proxy alrededor de la propiedad virtual para que la propiedad pueda admitir una carga lenta y un seguimiento de cambios más eficiente. Consulte ¿Qué efectos pueden tener las palabras clave virtuales 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 Entity Framework. Entity Framework requiere que sus propiedades de navegación estén marcadas como virtuales para que se admita una carga lenta y un seguimiento de cambios eficiente. Ver Requisitos para la Creación de Proxies POCO .
El Entity Framework utiliza la herencia para admitir esta funcionalidad, por lo que requiere que ciertas propiedades estén marcadas como virtuales en los POCO de su clase base. Literalmente crea nuevos tipos que se derivan de sus tipos de POCO. Por lo tanto, su POCO está actuando como un tipo base para las subclases creadas dinámicamente del Entity Framework. Eso es lo que quise decir con "crear un proxy alrededor".

Las subclases creadas dinámicamente que crea Entity Framework se vuelven aparentes cuando se usa Entity Framework en tiempo de ejecución, no en tiempo de compilación estática. Y solo si habilita las funciones de seguimiento lento de cambios de Entity Framework o cambio. Si opta por no utilizar nunca las funciones de carga diferida o de seguimiento del Entity Framework (que no es el predeterminado), no necesita declarar ninguna de sus propiedades de navegación como virtuales. Entonces, usted es responsable de cargar esas propiedades de navegación, ya sea utilizando lo que Entity Framework denomina "carga impaciente", o bien recuperar manualmente los tipos relacionados en múltiples consultas de bases de datos. Sin embargo, puede y debe usar las funciones de carga lenta y cambio de seguimiento para sus propiedades de navegación en muchos escenarios.

Si tuviera que crear una clase independiente y marcar las propiedades como virtuales, y simplemente construir y usar instancias de esas clases en su propia aplicación, completamente fuera del alcance del Entity Framework, entonces sus propiedades virtuales no le darían nada. propio.

Editar para describir por qué las propiedades se marcarían como virtuales

Propiedades tales como:

public ICollection<RSVP> RSVPs { get; set; }

No son campos y no deben ser considerados como tales. Estos se denominan captadores y definidores y, en el momento de la compilación, se convierten en métodos.

//Internally the code looks more like this: public ICollection<RSVP> get_RSVPs() { return _RSVPs; } public void set_RSVPs(RSVP value) { _RSVPs = value; } private RSVP _RSVPs;

Es por eso que están marcados como virtuales para su uso en el Entity Framework, ya que permite que las clases creadas dinámicamente anulen las funciones de get y set generadas internamente. Si su captador / definidor de propiedades de navegación está trabajando para usted en el uso de Entity Framework, intente revisarlas solo a propiedades, recompilar, y ver si Entity Framework puede funcionar correctamente:

public virtual ICollection<RSVP> RSVPs;