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

EF Core添加新Entity生成负Id 数据库Id值正常如何排查解决?

EF Core添加实体后返回Id为负值但数据库自增Id正常问题

我在尝试添加新的Container实体时遇到问题:添加实体后,返回的数据集里显示的Id为负值,但我的SQL数据库中刚插入的Container的Id是正确的下一个自增值。

我查阅过相关资料,类似问题多出现在添加实体前先执行Update操作的场景,但我没有找到首次添加实体时出现该错误的相关说明。

我仅实例化了一个新的Container对象,将其添加到ProductContext的Containers DbSet中,相关代码如下:

public class ProductService : IProductService 
{
    private readonly IProductContext _productContext;
    public ProductService(IProductContext productContext)
    {
        _productContext = productContext;
    }

    public Container CreateContainer(Container container, int currentUserId)
    {
        _productContext.Containers.Add(container);
        _productContext.SaveChangesAsync();
        return container;
    }
}

单步调试时可以看到,初始状态下Id为0:
创建Id为0的Box 13

执行保存操作后,container的Id变为-2147482645:
负Id展示

但查询数据库可以看到对应的记录Id为正确的下一个自增值,该值没有同步更新到实体对象上,实体一直保留-2147482645的负Id值。


实体定义

我的Container实体定义如下:

public class Container : BaseEntity
{
    public Container()
    {
        this.ChildContainers = new HashSet<Container>();
        this.InventoryItems = new HashSet<InventoryItem>();
    }

    public ICollection<Container> ChildContainers { get; set; }
    public ICollection<InventoryItem> InventoryItems { get; set; }
    public Location Location { get; set; }
    public int? LocationId { get; set; }
    public string Name { get; set; }

    [ForeignKey("ParentContainerId")]
    public Container ParentContainer { get; set; }

    public int? ParentContainerId { get; set; }
}

继承的BaseEntity类定义如下:

public abstract class BaseEntity
{
    [Key]
    public virtual int Id { get; set; }

    [DefaultValue(false)]
    public virtual bool IsDeleted { get; set; }
    protected virtual object Actual => this;

    public override bool Equals(object obj)
    {
        if (!(obj is BaseEntity other))
            return false;

        if (ReferenceEquals(this, other))
            return true;

        if (Actual.GetType() != other.Actual.GetType())
            return false;

        if (Id == 0 || other.Id == 0)
            return false;

        return Id == other.Id;
    }

    public static bool operator ==(BaseEntity a, BaseEntity b)
    {
        if (a is null && b is null)
            return true;

        if (a is null || b is null)
            return false;

        return a.Equals(b);
    }

    public static bool operator !=(BaseEntity a, BaseEntity b)
    {
        return !(a == b);
    }

    public override int GetHashCode()
    {
        return (Actual.GetType().ToString() + Id).GetHashCode();
    }

    public DateTime CreatedDate { get; set; }
    public DateTime UpdatedDate { get; set; }
}

SaveChangesAsync重写实现

我重写的SaveChangesAsync方法实现如下:我认为这部分不会影响Id生成,因为Id在进入该方法前就已经被赋值了。

public override async Task<int> SaveChangesAsync(CancellationToken cancellationToken = new CancellationToken())
{
    var entries = ChangeTracker
        .Entries()
        .Where(e => e.Entity is BaseEntity && (
                e.State == EntityState.Added
                || e.State == EntityState.Modified));

    foreach (var entityEntry in entries)
    {
        ((BaseEntity)entityEntry.Entity).UpdatedDate = DateTime.Now;

        if (entityEntry.State == EntityState.Added)
        {
            ((BaseEntity)entityEntry.Entity).CreatedDate = DateTime.Now;
        }
    }

    return await base.SaveChangesAsync();
}

编辑1:同步调用SaveChanges相关说明

有观点认为我同步调用异步SaveChangesAsync方法可能引发该问题,但我认为这不是根本原因,因为Id在Add方法执行阶段就已经被修改了。
调试截图


内容的提问来源于stack exchange,提问作者Chris Hobbs

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 13:54:03