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

EF更新含Guid主键与Identity列的记录时触发无法更新标识列错误

EF Core脚手架生成标识列后更新报错问题及解决办法

问题场景

我有一个应用程序,使用以下EF Core脚手架命令生成数据库实体:

dotnet ef dbcontext scaffold "Server=MyServer;Database=MyDatabase;Trusted_Connection=True;Trust Server Certificate=true" 
       Microsoft.EntityFrameworkCore.SqlServer -o Entities -f --no-onconfiguring

生成完成后,目标表的RecNo列被配置为:

entity.Property(e => e.RecNo).ValueGeneratedOnAdd();

但尝试更新该表记录时,出现以下错误:

Microsoft.EntityFrameworkCore.DbUpdateException: 保存实体更改时发生错误。请查看内部异常了解详细信息。
Microsoft.Data.SqlClient.SqlException (0x80131904): 无法更新标识列 'RecNo'。

原本以为ValueGeneratedOnAdd()会在新增和更新时都生效,实际并非如此,希望找到解决办法,优先在脚手架阶段处理。

解决方案

1. 脚手架阶段直接修正(推荐)

方法一:使用--data-annotations参数生成数据注解

EF Core脚手架默认生成Fluent API配置,改用--data-annotations参数后,会自动识别SQL Server的标识列,并生成对应的[DatabaseGenerated(DatabaseGeneratedOption.Identity)]注解,明确告知EF该列仅在新增时由数据库生成,更新时无需修改。

修改后的脚手架命令:

dotnet ef dbcontext scaffold "Server=MyServer;Database=MyDatabase;Trusted_Connection=True;Trust Server Certificate=true" 
       Microsoft.EntityFrameworkCore.SqlServer -o Entities -f --no-onconfiguring --data-annotations

生成的实体类中RecNo列会带有如下配置:

[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int RecNo { get; set; }

这种配置下,EF在生成Update语句时会自动忽略该列,避免报错。

方法二:自定义脚手架模板(适配多次生成场景)

如果需要长期复用特定配置,可以自定义EF Core脚手架模板:

  • 先安装模板工具:dotnet new install Microsoft.EntityFrameworkCore.Templates
  • 导出模板到本地目录:dotnet new ef-templates -o EFTemplates
  • 修改EntityTypeConfiguration.cs.t4模板中标识列的配置逻辑,确保生成的Fluent API明确标记该列的生成规则:
<# if (property.IsIdentity) { #>
    entity.Property(e => e.<#= property.Name #>)
        .ValueGeneratedOnAdd()
        .Metadata.SetAfterSaveBehavior(PropertySaveBehavior.Ignore);
<# } #>

后续脚手架生成时使用自定义模板即可自动应用正确配置。

2. 手动修改生成代码(临时应急)

如果脚手架阶段无法调整,生成代码后可手动修改配置:

方式一:修改Fluent API配置

在DbContext的实体配置中添加SetAfterSaveBehavior:

entity.Property(e => e.RecNo)
    .ValueGeneratedOnAdd()
    .Metadata.SetAfterSaveBehavior(PropertySaveBehavior.Ignore);

该配置强制EF在更新实体时忽略RecNo列,无论属性值是否被修改,都不会将其包含在Update语句中。

方式二:添加数据注解

在实体类的RecNo属性上添加数据库生成注解:

[DatabaseGenerated(DatabaseGeneratedOption.Identity)]

若RecNo是表的主键,还需添加[Key]注解(脚手架通常会自动生成)。

内容的提问来源于stack exchange,提问作者Jim Wilcox

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 09:53:10