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

EF查询返回空Guid主键,调用SaveChanges触发DbUpdateConcurrencyException如何解决

问题根因与解决方案

核心问题是EF Core查询返回的Invoice实体Id属性未被正确赋值为数据库中的值,默认保持Guid.Empty,导致SaveChanges时生成的更新语句用WHERE Id = '00000000-0000-0000-0000-000000000000'作为筛选条件,匹配不到行,因此抛出DbUpdateConcurrencyException异常。

导致Id属性未被正确赋值的常见原因及对应解决方案如下:

  • 未显式指定主键,约定识别失效
    EF Core默认会将名为Id/类名+Id的属性识别为主键,但存在自定义构造函数、局部模型配置等场景时可能触发约定失效。你可以任选一种方式显式指定主键:
    1. 在Id属性上加[Key]数据注解:
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public Guid Id { get; set; }
    
    1. 在OnModelCreating的Invoice配置中新增主键声明:
    modelBuilder.Entity<Invoice>(entity =>
    {
        // 新增这行显式指定主键
        entity.HasKey(e => e.Id);
        entity.Property(e => e.Id).ValueGeneratedOnAdd();
        entity.Property(e => e.InvoiceNumber);
    });
    
  • 自定义构造函数干扰EF Core实体物化逻辑
    EF Core会优先匹配参数名和列名对应的构造函数做实体实例化,你的自定义构造函数中存在名为id的参数,但是你将该参数赋值给了FileId而非实体的Id属性,就算加了无参构造也可能存在绑定优先级问题。可通过以下方式解决:
    1. 若该自定义构造函数非必须,可直接删除,仅保留无参构造
    2. 若需要保留,可显式指定EF Core使用无参构造实例化实体(EF Core 3.0+支持):
    modelBuilder.Entity<Invoice>()
        .HasConstructorBinding(
            ConstructorBindingFactory.CreateBinding(
                typeof(Invoice).GetConstructor(Type.EmptyTypes), 
                new PropertyParameterBinding[0]));
    
  • 局部配置覆盖了映射规则
    检查OnModelCreatingPartial方法中的配置,确认没有将Id属性标记为Ignore,也没有将其他属性指定为Invoice的主键。

你可以先输出生成的查询SQL验证:如果查询语句中没有包含Id列,说明Id未被EF Core识别为映射属性,优先检查映射配置;如果查询语句包含Id列但实体Id仍为空,优先检查构造函数绑定逻辑。


内容的提问来源于stack exchange,提问作者Philippe Balleydier

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 15:24:04