Saltar al contenido

La propiedad de navegación debe ser virtual, ¿no es necesaria en ef core?

Solución:

virtual nunca fue requerido en EF. Solo fue necesario si desea soporte de carga diferida.

Dado que EF Core aún no admite la carga diferida, actualmente virtual no tienen ningún significado especial. Lo haría cuando (y si) agregan soporte de carga diferida (hay un plan para hacerlo).

Actualizar: A partir de EF Core 2.1, ahora se admite la carga diferida. Pero tan pronto como no agregue el paquete Microsoft.EntityFrameworkCore.Proxies y lo habilite a través de UseLazyLoadingProxies, la respuesta original aún se aplica.

Sin embargo, si lo hace, las cosas cambian por completo debido a la falta del control de suscripción en la implementación inicial: requiere todos sus propiedades de navegación para ser virtual. Lo cual no tiene sentido para mí, será mejor que no lo uses hasta que se arregle. Si realmente necesita una carga diferida, utilice el enfoque de carga diferida sin proxies alternativo, en cuyo caso nuevamente virtual no importa.

Las cosas han cambiado desde que se escribió la respuesta aceptada. En 2018, la carga diferida ahora es compatible a partir de Entity Framework Core 2.1 para dos enfoques diferentes.

La forma más simple de las dos es usar proxies, y esto requerirá que las propiedades deseadas para cargarse de forma diferida se definan con virtual. Para citar de la página vinculada:

La forma más sencilla de utilizar la carga diferida es instalando el paquete Microsoft.EntityFrameworkCore.Proxies y habilitándolo con una llamada a UseLazyLoadingProxies. […] EF Core habilitará la carga diferida para cualquier propiedad de navegación que pueda anularse, es decir, debe ser virtual y estar en una clase de la que se pueda heredar.

Y aquí está el código de muestra proporcionado:

public class Blog
{
    public int Id { get; set; }
    public string Name { get; set; }

    public virtual ICollection<Post> Posts { get; set; }
}

public class Post
{
    public int Id { get; set; }
    public string Title { get; set; }
    public string Content { get; set; }

    public virtual Blog Blog { get; set; }
}

Hay otra forma de realizar la carga diferida sin proxies, que es inyectar ILazyLoader en el constructor del tipo de datos. Esto se explica aquí.

En resumen, hay dos formas de realizar la carga diferida: con y sin proxies. virtual es requerido si y solo si desea admitir la carga diferida con proxies. De lo contrario, no lo es.

La palabra clave virtual nunca ha sido REQUERIDA … Es opcional.

¿Qué cambia?

1. si declara su propiedad virtual:

Su propiedad virtual (por defecto) no se cargará de inmediato al consultar el objeto principal. Se recuperará de la base de datos SÓLO si intenta acceder a él o accede a uno de sus componentes.

Y esto se llama carga diferida.

2. si lo declara no virtual:

Su propiedad se cargará (por defecto) de inmediato junto con todas las demás propiedades en su entidad principal. Esto significa que su propiedad estará lista para acceder: ya ha sido recuperada. La entidad no tendrá que volver a consultar la base de datos porque accedes a esta propiedad.

A esto se le llama cargar con entusiasmo.

Mi opinión :

Con más frecuencia, elijo cargar con entusiasmo (no virtual) porque la mayoría de las veces, necesito que todas las propiedades de cada entidad se utilicen sin tener que volver a consultar (más rápido en el caso de que realmente desee que todo sea rápido) pero si accede a esta propiedad solo de vez en cuando (no enumera nada) y desea más a menudo solo el resto de la información, excepto ESTA, luego hágalo virtual para que esta propiedad no ralentice el resto de la consulta solo para unos pocos accesos.

Espero que esto haya quedado claro …

Ejemplos:

Donde NO usaría virtual (con entusiasmo):

foreach(var line in query)
{
    var v = line.NotVirtual; // I access the property for every line
}

Donde usaría carga virtual o diferida:

foreach(var line in query)
{
   if(line.ID == 509)        // because of this condition
   var v = line.Virtual; // I access the property only once in a while
}

una última cosa :

Si no consulta más de 1000 líneas de una base de datos, lo que elija no tendrá un gran efecto. Además, puede declarar estas propiedades virtuales y si desea probar al revés, solo tiene que hacer esto (Entidad 4.0):

context.LazyLoadingEnabled = false;

Cancelará el efecto virtual.

Editar

Para versiones más recientes de EF:

WhateverEntities db = new WhateverEntities() 
db.Configuration.LazyLoadingEnabled = false;
¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *