İlgili Verilerin Gecikmeli Yüklenmesi

Proxy'lerle yavaş yükleme

Yavaş yükleme kullanmanın en basit yolu, Microsoft.EntityFrameworkCore.Proxies paketini yükleyip çağrısıyla UseLazyLoadingProxiesetkinleştirmektir. Örnek:

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    => optionsBuilder
        .UseLazyLoadingProxies()
        .UseSqlServer(myConnectionString);

Veya AddDbContext kullanırken:

.AddDbContext<BloggingContext>(
    b => b.UseLazyLoadingProxies()
          .UseSqlServer(myConnectionString));

EF Core daha sonra geçersiz kılınabilecek herhangi bir gezinti özelliği için gecikmeli yüklemeyi etkinleştirir; başka bir ifadeyle ve öğesinden devralınabilecek bir sınıfta olmalıdır virtual . Örneğin, aşağıdaki varlıklarda Post.Blog ve Blog.Posts gezinti özellikleri yavaş yüklenir.

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; }
}

Uyarı

Gecikmeli yükleme gereksiz ek veritabanı gidiş dönüşlerinin oluşmasına neden olabilir (N+1 sorunu olarak adlandırılır) ve bunu önlemek için dikkatli olunmalıdır. Diğer ayrıntılar için performans bölümüne bakın.

Proxy'ler olmadan gecikmeli yükleme

Proxy'ler olmadan yavaş yükleme, Varlık Türü Oluşturucuları'nda açıklandığı gibi hizmeti bir varlığa ekleyerek ILazyLoader çalışır. Örnek:

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;
    }
}

Bu yöntem, varlık türlerinin devralınmasını veya gezinti özelliklerinin sanal olmasını gerektirmez ve ile new oluşturulan varlık örneklerinin bir bağlama eklendikten sonra yavaş yüklenmesine izin verir. Ancak, Microsoft.EntityFrameworkCore.Abstractions paketinde tanımlanan hizmete bir başvuru ILazyLoader gerektirir. Bu paket, çok az tür kümesi içerir, böylece buna bağlı olarak çok az etkisi olur. Ancak, varlık türlerindeki EF Core paketlerine bağlı olarak tamamen kaçınmak için yöntemini temsilci olarak eklemek ILazyLoader.Load mümkündür. Örnek:

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;
    }
}

Yukarıdaki kod, temsilciyi kullanmayı biraz daha temiz hale getirmek için bir uzantı yöntemi kullanır Load :

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;
    }
}

Dekont

Gecikmeli yükleme temsilcisi için oluşturucu parametresi "lazyLoader" olarak adlandırılmalıdır. Gelecek bir sürüm için planlanandan farklı bir ad kullanacak yapılandırma.