EF Core的Add函数返回负ID

31
我今天在尝试保存实体并返回其id时,注意到了一个奇怪的问题。
之前: 在添加到数据库之前,Id为0 之后: 现在id已经变成了负数 我考虑过是在调用saveChanges()之前出了问题,但是对于另一个类似设置的实体,它可以正常工作。
附:我使用unit of work在最后一起保存所有更改。
原因是什么?

3
请不要使用截图来展示代码,而是将相关的代码复制粘贴到您的问题中,并应用代码格式。 - user247702
2个回答

23

在保存更改之前,它将为负。只需在上下文中调用Save

_dbContext.Locations.Add(location);
_dbContext.Save();

保存后,您将拥有数据库中的ID。您可以使用事务,在获得ID后出现问题时回滚。

另一种方法是不使用数据库内置的IDENTITY字段,而是自己实现它们。当您有大量批量插入操作时,这可能非常有用,但是它也有代价 - 实现起来并不容易。


8
EF Core 3.1 中的行为发生了改变,添加实体时其 ID 又变回了 0。 - Jan Palas
现在发现这个问题挺搞笑的,因为它使得无法使用TPH来实现一对一的主外键关系,因为最终会产生多个值为0的主键。即使通过导航属性进行赋值也会导致这种情况的出现。 - Captain Prinny

1

显然,这不是一个错误,而是一种特性:https://github.com/aspnet/EntityFrameworkCore/issues/6147

覆盖这个行为并不太困难,可以像这样进行:

 public class IntValueGenerator : TemporaryNumberValueGenerator<int>
 {
     private int _current = 0;

     public override int Next(EntityEntry entry)
     {
         return Interlocked.Increment(ref _current);
     }    
 }

然后在这里引用自定义值生成器:
public class CustomContext: DbContext
{
    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        foreach (var type in modelBuilder.Model.GetEntityTypes().Select(c => c.ClrType))
        {
            modelBuilder.Entity(type, b =>
            {              
                b.Property("Id").HasValueGenerator<IntValueGenerator>();
            });
        }
        base.OnModelCreating(modelBuilder);
    }
}

这将导致临时ID从“1”开始递增,但是在尝试保存时需要更多的努力来避免键冲突。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接