.net EF Core 7 -添加新对象,但ID值具有临时值

fdx2calv  于 2023-06-25  发布在  .NET
关注(0)|答案(1)|浏览(129)

从EF 6升级到EF Core 7,我无法解决这个问题。在我们的客户端上,我们为小于零的对象分配新的id值。当我们将对象Map到EF6时,它会意识到它是一个新对象,因为我们在父对象上调用了Entry(entity).State = EntityState.Added;,并且添加了所有的子对象。当将其插入数据库时,通过SQL Server为对象分配一个新值,并更新所有对象上的所有引用。
比如说,

namespace EFCorePlayground
{
    public class AtCalc
    {
        public long Id { get; set; }
        public string Name { get; set; }
    }
}

namespace EFCorePlayground.Config
{
    public class AtCalcConfig : IEntityTypeConfiguration<AtCalc>
    {
        public void Configure(EntityTypeBuilder<AtCalc> builder)
        {
            // table
            builder.ToTable("AtCalc");

            // key
            builder.Property(e => e.Id).ValueGeneratedOnAdd();
            builder.HasKey(e => e.Id);

            builder.OwnsOne(e => e.Details);
        }
    }
}

在服务器上,如果我创建了一个新对象,那么我会得到一个错误,现在它试图保存ID为-1的MyObject,为什么?

using EFCorePlayground;
using EFCorePlayground.Config;

var context = new DataContext();
var m = new AtCalc { Id = -1, Name = "bob" };

context.Add(m).State = Microsoft.EntityFrameworkCore.EntityState.Added;
context.SaveChanges();

Console.WriteLine("Hello, World!");

我得到这个错误:
IDENTITY_INSERT设置为OFF时,无法在表“AtCalc”中插入标识列的显式值
如何让EF Core像EF6一样工作,并赋予它一个新的Id值?我在处理子对象时也会遇到这个问题,但我猜我遗漏了一个解决方案。
根据this页面,这应该工作?有人能给我指个方向吗?
编辑:我不希望它插入-1,我只是在客户端给它一个唯一的值,这样,如果我在保存时必须在其他地方引用该值,它就会知道要使用哪个对象。正如有人在下面的评论中所说,EF6忽略在ID列上设置的任何值,并使用数据库中的值覆盖它,有没有一种方法可以配置此功能?

kq0g1dla

kq0g1dla1#

因为您指定了Id将自行增加(builder.Property(e => e.Id).ValueGeneratedOnAdd();),但必须手动设置,这是不可能的
除非你完全禁用它

builder.Property(e => e.Id).ValueGeneratedNever();

或者像下面的代码一样临时禁用它
必须在“SET IDENTITY_INSERT“上启动

using (var transaction = context.Database.BeginTransaction())
        {
            AtCalc m = new AtCalc { Id = -1, Name = "bob" };

            context.Database.ExecuteSqlInterpolated($"SET IDENTITY_INSERT dbo.AtCalc ON;");
            context.Add(m).State = Microsoft.EntityFrameworkCore.EntityState.Added;
            context.SaveChanges();
            context.Database.ExecuteSqlInterpolated($"SET IDENTITY_INSERT dbo.AtCalc OFF");
            transaction.Commit();
        }

相关问题