Entity Framework SQLite Provider插入异常:顺序错乱及数据丢失求助
Entity Framework SQLite 插入异常问题
使用Entity Framework SQLite提供程序时,执行初始化操作遇到以下异常:
- 调用
Initialize方法时,dbContext仅插入2条TaskTypeModel记录,丢失1条插入语句 - 无任何报错信息,.NET 6和.NET 7版本均复现此问题
相关代码及追踪结果
页面代码
@page "/installation" @inject ApplicationDbContext dbContext <MudButton Variant="Variant.Filled" Color="Color.Primary" OnClick="Initialize">Initialize</MudButton> @code { void Initialize() { var facebook = dbContext.Sites.Add(new SiteModel { Name="Facebook", Url="https://www.facebook.com" }); dbContext.TaskTypes.AddRange(new List<TaskTypeModel>() { new(){ Name="GroupPost", Site=facebook.Entity }, new(){ Name="PagesssPost", Site=facebook.Entity }, new(){ Name="ScrapeGroupMembers", Site=facebook.Entity } }); var entries = dbContext.ChangeTracker.Entries(); foreach(var entry in entries) { Console.WriteLine(entry.Entity); } } }
追踪结果
Project.Models.SiteModel
Project.Models.TaskTypeModel
Project.Models.TaskTypeModel
实体类代码
SiteModel.cs
public class SiteModel { public int Id { get; set; } public string Name { get; set; } = null!; [Url(ErrorMessage = "Invalid url format")] public string Url { get; set; } = null!; }
TaskTypeModel.cs
public class TaskTypeModel { public int Id { get; set; } public string Name { get; set; } = null!; public int SiteId { get; set; } public SiteModel Site { get; set; } = null!; }
DbContext配置代码
builder.Entity<TaskTypeModel>().ToTable("TaskTypes"); builder.Entity<TaskTypeModel>() .HasOne(t => t.Site) .WithOne() .HasForeignKey<TaskTypeModel>(t => t.SiteId); builder.Entity<TaskTypeModel>() .HasIndex(t => t.SiteId) .IsUnique(false);
问题原因及解决方案
原因
DbContext中错误地将SiteModel与TaskTypeModel的关系配置为一对一(WithOne()),但实际业务场景是一对多(一个Site对应多个TaskType)。一对一关系下,EF会认为一个Site只能关联一个TaskType,后续添加的同Site的TaskType会覆盖之前的,导致最终只保留2条有效追踪记录。
解决方案
修改DbContext的关系配置,将WithOne()改为WithMany(),明确一对多关系:
builder.Entity<TaskTypeModel>().ToTable("TaskTypes"); builder.Entity<TaskTypeModel>() .HasOne(t => t.Site) .WithMany() // 改为一对多,若SiteModel中没有导航属性则留空 .HasForeignKey<TaskTypeModel>(t => t.SiteId); builder.Entity<TaskTypeModel>() .HasIndex(t => t.SiteId) .IsUnique(false);
如果需要在SiteModel中添加反向导航属性,可修改SiteModel:
public class SiteModel { public int Id { get; set; } public string Name { get; set; } = null!; [Url(ErrorMessage = "Invalid url format")] public string Url { get; set; } = null!; // 添加反向导航属性 public ICollection<TaskTypeModel> TaskTypes { get; set; } = new List<TaskTypeModel>(); }
同时更新DbContext配置:
builder.Entity<TaskTypeModel>() .HasOne(t => t.Site) .WithMany(s => s.TaskTypes) // 指定反向导航属性 .HasForeignKey<TaskTypeModel>(t => t.SiteId);
修改后重新运行,即可正常插入3条TaskTypeModel记录。
内容的提问来源于stack exchange,提问作者david
相关产品推荐
相关产品推荐

