Pemuatan Malas Data Terkait
Pemuatan malas dengan proksi
Cara paling sederhana untuk menggunakan pemuatan malas adalah dengan menginstal paket Microsoft.EntityFrameworkCore.Proxies dan mengaktifkannya dengan panggilan ke UseLazyLoadingProxies
. Contohnya:
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
=> optionsBuilder
.UseLazyLoadingProxies()
.UseSqlServer(myConnectionString);
Atau saat menggunakan AddDbContext:
.AddDbContext<BloggingContext>(
b => b.UseLazyLoadingProxies()
.UseSqlServer(myConnectionString));
EF Core kemudian akan mengaktifkan pemuatan malas untuk properti navigasi apa pun yang dapat ditimpa --yaitu, harus virtual
dan pada kelas yang dapat diwariskan. Misalnya, dalam entitas berikut, Post.Blog
properti navigasi dan Blog.Posts
akan dimuat malas.
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; }
}
Peringatan
Pemuatan malas dapat menyebabkan roundtrips database tambahan yang tidak diperlukan terjadi (yang disebut masalah N+1), dan perawatan harus dilakukan untuk menghindari hal ini. Lihat bagian performa untuk detail selengkapnya.
Pemuatan malas tanpa proksi
Pemuatan malas tanpa proksi berfungsi dengan menyuntikkan ILazyLoader
layanan ke entitas, seperti yang dijelaskan dalam Konstruktor Jenis Entitas. Contohnya:
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;
}
}
Metode ini tidak mengharuskan jenis entitas diwariskan dari atau properti navigasi menjadi virtual, dan memungkinkan instans entitas yang dibuat dengan new
untuk malas-load setelah dilampirkan ke konteks. Namun, ini memerlukan referensi ke ILazyLoader
layanan, yang didefinisikan dalam paket Microsoft.EntityFrameworkCore.Abstractions . Paket ini berisi sekumpulan jenis minimal sehingga ada sedikit dampak tergantung padanya. Namun, untuk sepenuhnya menghindari tergantung pada paket EF Core apa pun dalam jenis entitas, dimungkinkan untuk menyuntikkan ILazyLoader.Load
metode sebagai delegasi. Contohnya:
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;
}
}
Kode di atas menggunakan Load
metode ekstensi untuk membuat penggunaan delegasi sedikit lebih bersih:
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;
}
}
Catatan
Parameter konstruktor untuk delegasi pemuatan malas harus disebut "lazyLoader". Konfigurasi untuk menggunakan nama yang berbeda dari ini direncanakan untuk rilis mendatang.