首页 > 其他 > 详细

EF Core 通过延迟加载获取导航属性数据

时间:2020-05-25 00:03:14      阅读:80      评论:0      收藏:0      [点我收藏+]
原文: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);

EF Core 通过延迟加载获取导航属性数据

原文:https://www.cnblogs.com/lonelyxmas/p/12953625.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!