EntityFramework Core延迟加载(LazyLoad)

本文介绍了EntityFramework Core中的延迟加载,即惰性加载概念,详细讲解了如何通过Microsoft.EntityFrameworkCore.Proxies、ILazyLoader以及Action<object, string>实现延迟加载。同时,还探讨了如何处理在序列化时可能出现的循环依赖问题,提供了解决方案。" 125031674,13441609,"JavaScript数组方法详解:indexOf, lastIndexOf, join与toString

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、延迟加载介绍

延迟加载又叫惰性加载(Lazy Loading):即在需要或者使用的时候加载数据。

此功能是在EF Core 2.1中引入的。

2、使用延迟加载

2.1 使用 Microsoft.EntityFrameworkCore.Proxies

直接重写OnConfiguring方法配置UseLazyLoadingProxies()

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

或者在Configing方法中添加

services.AddDbContext<UserContext>(
    b => b.UseLazyLoadingProxies()
          .UseSqlServer(connectionString));
2.2使用ILazyLoader注入到构造中
  • 定义实体,并构造注入ILazyLoader
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;
    }
}
注意:构造注入的方法是私有的,因为ILazyLoader只和EFCore进行耦合。
2.3使用Action<object, string>让上面的ILazyLoader解耦
  • 使用注入委托的方式进行解耦

    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;
        }
    }
    
  • 扩展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;
        }
    }
    

3、处理序列化时的循环依赖

添加AddJsonOptions
public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc()
        .AddJsonOptions(
            options => options.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore
        );
}

或者使用 [JsonIgnore] 标记属性表示序列化的时候不进行序列化。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值