You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 02:04:52