Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
Carregamento lento com proxies
A maneira mais simples de usar o carregamento lento é instalando o pacote Microsoft.EntityFrameworkCore.Proxies e habilitando-o com uma chamada para UseLazyLoadingProxies. Por exemplo:
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
=> optionsBuilder
.UseLazyLoadingProxies()
.UseSqlServer(myConnectionString);
Ou ao usar AddDbContext:
.AddDbContext<BloggingContext>(
b => b.UseLazyLoadingProxies()
.UseSqlServer(myConnectionString));
O EF Core habilitará o carregamento lento para qualquer propriedade de navegação que possa ser substituída, ou seja, deve ser virtual e em uma classe da qual possa ser herdado. Por exemplo, nas entidades a seguir, as propriedades de navegação Post.Blog e Blog.Posts serão carregadas sob demanda.
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; }
}
Aviso
O carregamento lento pode fazer com que viagens de ida e volta extras desnecessárias do banco de dados ocorram (o chamado problema N+1) e deve-se tomar cuidado para evitar isso. Consulte a seção de desempenho para obter mais detalhes.
Carregamento lento sem proxies
O carregamento lento sem proxies funciona injetando o ILazyLoader serviço em uma entidade, conforme descrito em Construtores de Tipo de Entidade. Por exemplo:
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;
}
}
Esse método não exige que os tipos de entidade sejam herdados a partir de ou que as propriedades de navegação sejam virtuais, permitindo que as instâncias de entidade criadas com new façam carregamento lento uma vez anexadas a um contexto. No entanto, ele requer uma referência ao ILazyLoader serviço, que é definido no pacote Microsoft.EntityFrameworkCore.Abstractions . Esse pacote contém um conjunto mínimo de tipos para que haja pouco impacto dependendo dele. No entanto, para evitar completamente a dependência de qualquer pacote EF Core nos tipos de entidade, é possível injetar o método ILazyLoader.Load como um delegado. Por exemplo:
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;
}
}
O código acima usa um Load método de extensão para tornar o uso do delegado um pouco mais limpo:
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;
}
}
Observação
O parâmetro do construtor para o delegado de carregamento lento deve ser chamado de "lazyLoader". A configuração para usar um nome diferente disso está planejada para uma versão futura.