EF 6 调用插入而不是更新



这可能是一个重复的问题,但是在标题中搜索单词只会得到很多不相关的结果。

我有一个大致设置如下的实体:

public abstract class A
{
public GUID AId { get; set; }
public string SomeProperty { get; set; }
}
public class B : A
{
public string SomeOtherProperty { get; set; }
}

上下文具有B对象的public DbSet<B> BInstances { get; set; }。在OnModelCreating中,映射A设置为忽略,B映射到一个名为TableB的表。

AId字段不是自动生成的(不是标识字段(,但它在数据库和映射中都设置为主键。在数据库中,该字段定义为没有默认值的非空uniqueidentifier

在运行时,我正在使用其键加载B的实例(_token只是一个CancellationToken(:

var b = await (dbCtx.BInstances.FirstOrDefaultAsync(e => e.AId), _token));

然后,设置b属性,我尝试将其保存回数据库:

b.SomeOtherProperty = "some new text";
await (dbCtx.SaveChangesAsync(_token));

此时,我从数据库中收到">违反主键约束"错误,指出无法插入AId的值,因为它是重复的。当然,ID 已经在数据库中,我使用 ID 从那里加载实体。出于某种原因,EF 生成一个 INSERT 语句,而不是 UPDATE,我不明白为什么。

当我检查dbCtx.Entry(b).State时,它已经设置为EntityState.Modified.我很茫然 - 有人可以指出我做错了什么吗?我以前从未遇到过更新实体的问题,但我没有将 EF 与 GUID 主键一起使用(通常我使用long主键(。

我使用的是EF 6和.NET Framework 4.7.1。

谢谢大家的建议 - 事实证明这是我造成的映射问题。

在我的OnModelCreating()调用中,我在未从基类继承的类型上调用了MapInheritedProperties()(当然,除了object( - 这似乎引发了一个问题。共享基类的其他实体在映射调用中工作正常。

我还直接针对实体类调用ToTable()- 由于我不明白的原因,这破坏了我的表映射。一旦我将该调用移动到Map()内,它就开始按预期工作。

所以我从这个出发:

entity.ToTable("tablename");

对此:

entity.Map(m => m.ToTable("tablename"));

来解决问题。

希望这对未来的读者有用。

试试这个

b.SomeOtherProperty = "some new text";
dbCtx.BInstances.AddOrUpdate(b);
await (dbCtx.SaveChangesAsync(_token));

AddorUpdate 将更新您的 b 实例(如果已添加(。

最新更新