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

EF Core报错:IDENTITY_INSERT关闭时无法插入SiteCategory标识列值

解决多对多关联时的SqlIdentity插入错误

问题背景

拥有Tags、TagCategories和SiteCategory三张表,其中TagCategories作为中间表实现Tags与SiteCategory的多对多关系。在.NET Core 8项目中通过数据库脚手架生成对应模型及配置代码,创建新Tag并关联指定SiteCategory时触发错误:

SqlException: Cannot insert explicit value for identity column in table 'SiteCategory' when IDENTITY_INSERT is set to OFF。

模型构建代码

Tag模型构建代码

modelBuilder.Entity<Tag>(entity =>
{
    entity.HasKey(e => e.Indx);

    entity.Property(e => e.Tag1)
        .HasMaxLength(50)
        .HasColumnName("Tag");

    entity.HasMany(d => d.Categories).WithMany(p => p.Tags)
        .UsingEntity<Dictionary<string, object>>(
            "TagCategory",
            r => r.HasOne<SiteCategory>().WithMany()
                .HasForeignKey("CategoryId")
                .OnDelete(DeleteBehavior.ClientSetNull)
                .HasConstraintName("FK_TagCategories_SiteCategory"),
            l => l.HasOne<Tag>().WithMany()
                .HasForeignKey("TagId")
                .OnDelete(DeleteBehavior.ClientSetNull)
                .HasConstraintName("FK_TagCategories_Tags"),
            j =>
            {
                j.HasKey("TagId", "CategoryId");
                j.ToTable("TagCategories");
                j.IndexerProperty<int>("TagId").HasColumnName("TagID");
                j.IndexerProperty<int>("CategoryId").HasColumnName("CategoryID");
            });
});

SiteCategory模型构建代码

modelBuilder.Entity<SiteCategory>(entity =>
{
    entity.HasKey(e => e.Indx);

    entity.ToTable("SiteCategory");

    entity.Property(e => e.Category).HasMaxLength(18);
    entity.Property(e => e.ShowInSystem)
        .IsRequired()
        .HasDefaultValueSql("((1))");
});

原操作函数

public bool addTagAndTagCategory(Tag tag, int? categoryID)
{
        try
        {
            var siteCat = db.SiteCategories.Where(cat => cat.Indx == categoryID).FirstOrDefault();
            siteCat.Tags.Add(tag);
            db.Add(tag);
            //var TagCategory = new Dictionary<string, object>
            //    {
            //        { "TagId", tag.Indx },
            //        { "CategoryId", siteCat.Indx }
            //    };
            //db.Attach(TagCategory);
            db.SaveChanges();
            var res = tag.Indx != 0 ? true : false;
            return res;
        }
        catch
        {
            throw;
        }
}

解决方案

1. 确保SiteCategory主键配置为自增列

在SiteCategory的Fluent API配置中,添加主键自增的配置,明确告知EF该列由数据库自动生成:

modelBuilder.Entity<SiteCategory>(entity =>
{
    entity.HasKey(e => e.Indx);
    // 添加自增列配置
    entity.Property(e => e.Indx).UseIdentityColumn();

    entity.ToTable("SiteCategory");

    entity.Property(e => e.Category).HasMaxLength(18);
    entity.Property(e => e.ShowInSystem)
        .IsRequired()
        .HasDefaultValueSql("((1))");
});

2. 修改操作函数的关联逻辑

调整关联顺序,从新创建的Tag的Categories集合中添加已存在的SiteCategory,避免EF误将已存在的SiteCategory视为新实体插入:

public bool addTagAndTagCategory(Tag tag, int? categoryID)
{
    try
    {
        // 用Find替代Where+FirstOrDefault,更高效且确保实体被上下文跟踪
        var siteCat = db.SiteCategories.Find(categoryID);
        if (siteCat == null)
            return false;

        // 从Tag的关联集合添加已存在的分类
        tag.Categories.Add(siteCat);
        // 仅添加Tag到上下文,EF会自动处理中间表的插入
        db.Tags.Add(tag);
        db.SaveChanges();

        return tag.Indx != 0;
    }
    catch
    {
        throw;
    }
}

问题原因说明

  • 原配置未明确标记SiteCategory的Indx为自增列,EF可能尝试手动插入该列值,而数据库中该列是自增列,导致权限错误。
  • 原操作逻辑反向关联(从SiteCategory集合添加Tag),可能导致EF错误地将已存在的SiteCategory标记为待插入状态,调整关联顺序后可避免此问题。

内容的提问来源于stack exchange,提问作者muhammad tally

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 04:48:36