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

EF Core 7插入SQL Server标识列报错:IDENTITY_INSERT为OFF时无法显式插入值

解决EF Core插入标识列时的SqlException异常

问题场景

使用Entity Framework Core 7和ASP.NET Core Razor Pages开发时,向SQL Server的ZebraSubPrinters表插入数据触发以下异常:

SqlException
Cannot insert explicit value for identity column in table 'ZebraSubPrinters' when IDENTITY_INSERT is set to OFF.

相关代码与信息

  • 实体类定义:
public class ZebraSubPrinters
{
    public decimal ID { get; set; }
    public string BranchCode { get; set; }
    public string DisplayName { get; set; }
    public string Category { get; set; }
    public string PrinterName { get; set; }
    public string PrinterIP { get; set; }
    public bool IsActive { get; set; } = true;
}
  • 通用仓储插入与保存代码:
public virtual TEntity Insert(TEntity entity)
{
    var result = dbSet.AddAsync(entity).Result.Entity;

    return result;
}

public void Save()
{
    try
    {
        _basecontext.SaveChanges();
    }
    catch (Exception ex)
    {    
        throw;
    }    
}
  • 插入执行代码:
public void InsertZebraSubPrinters(ZebraSubPrinters printer)
{ 
    ZebraSubPrinters ZEB = new ZebraSubPrinters();
    ZEB.IsActive = printer.IsActive;
    ZEB.PrinterName = printer.PrinterName;
    ZEB.PrinterIP = printer.PrinterIP;
    ZEB.Category = printer.Category;
    ZEB.DisplayName = printer.DisplayName;
    ZEB.BranchCode = printer.BranchCode;

    aDCSupportUnitOfWork.ZebraSubPrinters.Insert(ZEB);
    aDCSupportUnitOfWork.ZebraSubPrinters.Save();              
}
  • SQL Server Profiler捕获的报错语句:
exec sp_executesql N'SET IMPLICIT_TRANSACTIONS OFF;
SET NOCOUNT ON;
INSERT INTO [ZebraSubPrinters] ([ID], [BranchCode], [Category], [CreatedBy], [CreatedDate], [DisplayName], [IsActive], [PrinterIP], [PrinterName], [SavedDate], [UpdatedBy], [UpdatedDate])
VALUES (@p0, @p1, @p2, @p3, @p4, @p5, @p6, @p7, @p8, @p9, @p10, @p11);
',N'@p0 decimal(18,2),@p1 nvarchar(4000),@p2 nvarchar(4000),@p3 nvarchar(4000),@p4 datetime2(7),@p5 nvarchar(4000),@p6 bit,@p7 nvarchar(4000),@p8 nvarchar(4000),@p9 datetime2(7),@p10 nvarchar(4000),@p11 datetime2(7)',@p0=0,@p1=N'10207',@p2=N'Green',@p3=NULL,@p4='0001-01-01 00:00:00',@p5=N'TANTAWY',@p6=1,@p7=NULL,@p8=NULL,@p9='0001-01-01 00:00:00',@p10=NULL,@p11='0001-01-01 00:00:00'

补充说明:ID列是主键且为标识列(增量1,1),数据库中数据类型为numeric(18,0),存储值为整数,实体类定义为decimal类型。

问题原因

EF Core未识别到ID属性是数据库的标识列,因此生成插入SQL时自动包含了ID字段(值为decimal类型的默认值0),而SQL Server默认禁止手动插入标识列的值,导致抛出异常。

解决方法

方法1:使用数据注解配置标识列

在实体类的ID属性上添加注解,明确告知EF Core该字段由数据库自动生成:

public class ZebraSubPrinters
{
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public decimal ID { get; set; }
    // 其他属性保持不变
    public string BranchCode { get; set; }
    public string DisplayName { get; set; }
    public string Category { get; set; }
    public string PrinterName { get; set; }
    public string PrinterIP { get; set; }
    public bool IsActive { get; set; } = true;
}

方法2:使用Fluent API配置标识列

在DbContext类的OnModelCreating方法中,通过Fluent API配置ID属性为标识列:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<ZebraSubPrinters>()
        .Property(p => p.ID)
        .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
    // 其他实体配置...
}

若要更贴合SQL Server标识列特性,也可使用:

modelBuilder.Entity<ZebraSubPrinters>()
    .Property(p => p.ID)
    .UseIdentityColumn();

额外注意事项

  1. 类型精度匹配:数据库中ID是numeric(18,0),可通过注解或Fluent API指定精度,避免EF生成不必要的小数位:
    // 数据注解方式
    [Column(TypeName = "numeric(18,0)")]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public decimal ID { get; set; }
    
    // Fluent API方式
    modelBuilder.Entity<ZebraSubPrinters>()
        .Property(p => p.ID)
        .HasColumnType("numeric(18,0)")
        .UseIdentityColumn();
    
  2. 禁止手动赋值:创建ZebraSubPrinters实例时,不要手动给ID赋值(当前代码未手动赋值,仅用默认值0,配置标识列后EF会自动忽略该值,不再生成到插入SQL中)。
  3. 更新Code First迁移:若使用Code First模式,配置完成后需生成新迁移并更新数据库,确保实体配置与数据库结构一致。

内容的提问来源于stack exchange,提问作者ahmed abdelaziz

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 17:01:00