zoukankan      html  css  js  c++  java
  • EF Core 通过延迟加载获取导航属性数据

    EF 6及以前的版本是默认支持延迟加载(Lazy Loading)的,早期的EF Core中并不支持,必须使用Include方法来支持导航属性的数据加载。
    当然在EF Core 2.1及之后版本中已经引入了延迟加载功能,详细实现原理可以查看官网(传送门)。
    下面记录一下,分别使用IncludeLazy Loading来支持导航属性的数据加载。

    Entity数据库实体

    简单的一个多对多关系,分别对应数据库中的3张表。学生和学校之间通过StuSchReg关联,相互之间可以通过导航属性获取数据。

    public class Student
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public virtual IList<StuSchReg> Regs { get; set; }
    }
    
    public class School
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public virtual IList<StuSchReg> Regs { get; set; }
    }
    public class StuSchReg
    {
        public int Id { get; set; }
        public int StdId { get; set; }
        [ForeignKey("StdId")]
        public virtual Student Student { get; set; }
    
        public int SchId { get; set; }
        [ForeignKey("SchId")]
        public virtual School School { get; set; }
    }
    

    通过导航属性获取数据

    数据查询需求:通过学校Id获取学校中所有学生的信息

    [HttpGet]
    [HttpPost]
    public async Task<JsonResult> Test(int id)
    {
        return await Task.Run(() =>
        {
            var school = dbContext.School.Find(id);
            var list = school.Regs.Select(d => new { d.Student.Id, d.Student.Name });
            return Success(list);
        });
    }
    

    这种情况下school.Regs会报错(未将对象引用到实例),断点查看会发现值为null。
    解决方法
    1.通过Include直接加载导航属性
    将获取school的语句修改一下,可以正常获取到数据。

    var school = dbContext.School
        .Include(d => d.Regs)
            .ThenInclude(d => d.Student)
        .FirstOrDefault(d => d.Id == id);
    

    2.开启EF Core的延迟加载功能
    使用延迟加载的最简单方式是安装 Microsoft.EntityFrameworkCore.Proxies 包,并通过调用 UseLazyLoadingProxies 来启用。
    例如:在DbContext的OnConfiguring方法中启用

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        optionsBuilder
            .UseLazyLoadingProxies()
            .UseSqlServer(myConnectionString);
    }
    

    或在使用AddDbContext时启用

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

    EF Core会为可重写的任何导航属性(必须是 virtual 且在可被继承的类上)启用延迟加载。
    这时候还原为最开始的调用方式,也可以正常获取到导航属性的数据了。

    var school = dbContext.School.Find(id);
    
  • 相关阅读:
    C# 利用TTS实现文本转语音
    Windows10提示“没有权限使用网络资源”的解决方案
    INSPIRED启示录 读书笔记
    INSPIRED启示录 读书笔记
    phpfpm的配置
    session 的工作原理
    MySQL 事务
    Redis各种数据类型的使用场景
    JavaScript 和Ajax跨域问题
    如何做URL静态化 和页面的静态化
  • 原文地址:https://www.cnblogs.com/cplemom/p/11499527.html
Copyright © 2011-2022 走看看