Entity Framework Core搭配SQLite时延迟加载失效问题求助
问题:Supply类中Employee属性为空,导致EmployeeName报错
我拥有Delivery类与Employee类,为方便将数据加载到DataGridView,给Supply类创建了EmployeeName属性以返回员工姓名(替代员工ID),但运行时Employee属性为空引发报错。已在DbContext配置中启用延迟加载代理,使用SQLite数据库,理论上功能应正常,但实际未生效。
Supply类代码
public partial class Supply : EntityBase { [Browsable(false)] public override int Id { get; set; } [DisplayName("Дата поставки")] public string Date { get; set; } = null!; [Browsable(false)] public int EmployeeId { get; set; } [Browsable(false)] public virtual Employee Employee { get; set; } = null!; [Browsable(false)] public virtual ICollection<Product> Products { get; set; } = new List<Product>(); [NotMapped] [DisplayName("Работник")] public string EmployeeName { get { using(var context = new IssuingOrdersDbContext()) { var item = context.Supplies.First(i=>i.Id==Id); return item.Employee.FullName; } } } }
DbContext配置代码
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) => optionsBuilder .UseLazyLoadingProxies() .UseSqlite("Data Source=D:\\СГАЭК\\БДиСУБД\\Сем2\\Курсовая\\IssuingOrdersDB.db");
解决方案
问题根源
- 延迟加载未触发:在
EmployeeName的getter中新建了独立的DbContext实例,这个上下文查询出的Supply对象没有被延迟加载代理包装,无法自动加载关联的Employee。 - 重复查询性能问题:每次获取
EmployeeName都发起一次数据库查询,效率极低,还容易引发上下文状态冲突。
修复步骤
方案1:显式加载关联数据(推荐)
在查询Supplies时,主动Include关联的Employee数据,确保加载时就获取到员工信息:
// 获取Supply列表时添加Include using (var context = new IssuingOrdersDbContext()) { var supplies = context.Supplies.Include(s => s.Employee).ToList(); // 将supplies绑定到DataGridView dataGridView1.DataSource = supplies; }
然后修改EmployeeName属性,无需再新建上下文:
[NotMapped] [DisplayName("Работник")] public string EmployeeName { get => Employee?.FullName ?? "未指定员工"; }
方案2:确保延迟加载正常工作(不推荐用于UI场景)
如果坚持使用延迟加载,需满足以下条件:
- 实体类为public非密封(你的
Supply是partial,符合要求) - 导航属性必须是virtual(
Employee属性已满足) - 必须使用加载实体的原始DbContext,不能在getter中新建上下文。但这种方式会导致DataGridView每次渲染行都触发一次数据库查询,性能很差,不建议使用。
方案3:投影查询直接获取所需数据
可以直接在查询时投影出包含员工姓名的匿名类型,避免处理实体关联:
using (var context = new IssuingOrdersDbContext()) { var supplyData = context.Supplies .Select(s => new { s.Id, s.Date, Работник = s.Employee.FullName }) .ToList(); dataGridView1.DataSource = supplyData; }
这种方式无需修改Supply类,直接获取绑定所需的数据。
内容的提问来源于stack exchange,提问作者Quasarka N.
相关产品推荐
相关产品推荐

