ASP.NET Core 3.0 EF Core查询多对多导航属性ProductInvoices返回null如何解决
问题原因
EF Core 默认不会自动加载关联的导航属性,你当前的查询仅获取了Invoice主表数据,未指定加载关联的ProductInvoices多对多联接表数据,因此该导航属性返回null。
解决方案
方案1:急加载(最适合编辑场景)
无需额外配置,查询时直接指定要加载的关联属性即可,性能最优。
- 先引入EF Core相关命名空间:
using Microsoft.EntityFrameworkCore;
- 修改查询代码:
// GET: Invoices/Edit public async Task<IActionResult> Edit(int? id) { var invoice = await _context.Invoices .Include(i => i.ProductInvoices) // 若需要同时加载关联的商品信息,可新增下方配置 // .ThenInclude(pi => pi.Product) .FirstOrDefaultAsync(i => i.InvoiceId == id); return View(invoice); }
方案2:显式加载
先查询主表数据,再手动触发关联属性加载,适合需要按条件判断是否加载关联数据的场景:
public async Task<IActionResult> Edit(int? id) { var invoice = await _context.Invoices.FirstOrDefaultAsync(i => i.InvoiceId == id); // 手动加载ProductInvoices集合 await _context.Entry(invoice) .Collection(i => i.ProductInvoices) .LoadAsync(); return View(invoice); }
方案3:懒加载(不推荐编辑场景使用,易产生N+1额外查询)
需要额外配置后,访问导航属性时会自动加载数据:
- 安装NuGet包:
Microsoft.EntityFrameworkCore.Proxies - 注册DbContext时启用懒加载代理:
services.AddDbContext<你的DbContext类名>(options => options.UseSqlServer("你的连接字符串") .UseLazyLoadingProxies() // 启用懒加载代理 );
- 将实体类的导航属性修改为
virtual修饰:
public class Invoice { // 其余属性不变 public virtual IList<ProductInvoice> ProductInvoices { get; set; } } public class Product { // 其余属性不变 public virtual IList<ProductInvoice> ProductInvoices { get; set; } }
补充优化建议
建议在DbContext的OnModelCreating方法中显式配置多对多联接表的复合主键,避免EF Core自动识别配置出现异常:
protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity<ProductInvoice>() .HasKey(pi => new { pi.ProductId, pi.InvoiceId }); // 其余模型配置 }
内容的提问来源于stack exchange,提问作者User456
相关产品推荐
相关产品推荐

