Bagikan melalui


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.