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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM