Nota:
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
Carga diferida con servidores proxy
La manera más sencilla de usar la carga diferida es instalar el paquete Microsoft.EntityFrameworkCore.Proxies y habilitarlo con una llamada a UseLazyLoadingProxies. Por ejemplo:
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
=> optionsBuilder
.UseLazyLoadingProxies()
.UseSqlServer(myConnectionString);
O cuando se usa AddDbContext:
.AddDbContext<BloggingContext>(
b => b.UseLazyLoadingProxies()
.UseSqlServer(myConnectionString));
A continuación, EF Core habilitará la carga diferida para cualquier propiedad de navegación que se pueda sobrescribir, es decir, debe ser virtual y en una clase de la que se pueda heredar. Por ejemplo, en las siguientes entidades, las Post.Blog propiedades de navegación y Blog.Posts se cargarán diferidamente.
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; }
}
Advertencia
La carga diferida puede provocar que se produzcan recorridos de ida y vuelta de base de datos adicionales innecesarios (el denominado problema N+1) y se debe tener cuidado para evitarlo. Consulte la sección de rendimiento para obtener más detalles.
Carga diferida sin servidores proxy
La carga diferida sin servidores proxy funciona insertando el servicio ILazyLoader en una entidad, como se describe en los Constructores de tipos de entidad. Por ejemplo:
public class Blog
{
private ICollection<Post> _posts;
public Blog()
{
}
private Blog(ILazyLoader lazyLoader)
{
LazyLoader = lazyLoader;
}
private ILazyLoader LazyLoader { get; set; }
public int Id { get; set; }
public string Name { get; set; }
public ICollection<Post> Posts
{
get => LazyLoader.Load(this, ref _posts);
set => _posts = value;
}
}
public class Post
{
private Blog _blog;
public Post()
{
}
private Post(ILazyLoader lazyLoader)
{
LazyLoader = lazyLoader;
}
private ILazyLoader LazyLoader { get; set; }
public int Id { get; set; }
public string Title { get; set; }
public string Content { get; set; }
public Blog Blog
{
get => LazyLoader.Load(this, ref _blog);
set => _blog = value;
}
}
Este método no requiere que los tipos de entidad se hereden de otros tipos o que las propiedades de navegación sean virtuales, y permite que las instancias de entidad creadas con new se carguen de forma diferida una vez adjuntas a un contexto. Sin embargo, requiere una referencia al ILazyLoader servicio, que se define en el paquete Microsoft.EntityFrameworkCore.Abstractions . Este paquete contiene un conjunto mínimo de tipos para que haya poco impacto en función de él. Sin embargo, para evitar depender completamente de los paquetes de EF Core en los tipos de entidad, es posible inyectar el ILazyLoader.Load método como delegado. Por ejemplo:
public class Blog
{
private ICollection<Post> _posts;
public Blog()
{
}
private Blog(Action<object, string> lazyLoader)
{
LazyLoader = lazyLoader;
}
private Action<object, string> LazyLoader { get; set; }
public int Id { get; set; }
public string Name { get; set; }
public ICollection<Post> Posts
{
get => LazyLoader.Load(this, ref _posts);
set => _posts = value;
}
}
public class Post
{
private Blog _blog;
public Post()
{
}
private Post(Action<object, string> lazyLoader)
{
LazyLoader = lazyLoader;
}
private Action<object, string> LazyLoader { get; set; }
public int Id { get; set; }
public string Title { get; set; }
public string Content { get; set; }
public Blog Blog
{
get => LazyLoader.Load(this, ref _blog);
set => _blog = value;
}
}
El código anterior usa un Load método de extensión para que el uso del delegado sea un poco más limpio:
public static class PocoLoadingExtensions
{
public static TRelated Load<TRelated>(
this Action<object, string> loader,
object entity,
ref TRelated navigationField,
[CallerMemberName] string navigationName = null)
where TRelated : class
{
loader?.Invoke(entity, navigationName);
return navigationField;
}
}
Nota:
El parámetro constructor del delegado de carga diferida debe llamarse "lazyLoader". Configuración para usar un nombre diferente al previsto para una versión futura.