• EntityFramework Core延迟加载(LazyLoad)


    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] 标记属性表示序列化的时候不进行序列化。

  • 相关阅读:
    面向过程(或者叫结构化)分析方法与面向对象分析方法到底区别在哪里?请根据自己的理解简明扼要的回答
    当下大部分互联网创业公司为什么都愿意采用增量模型来做开发?
    0
    计算机网络
    java基础
    java 多线程编程
    java类与对象,用程序解释
    修饰符的探讨
    java学习总结02
    java day1
  • 原文地址:https://www.cnblogs.com/cqxhl/p/12993293.html
Copyright © 2020-2023  润新知