EF 6调用INSERT而不是UPDATE

时间:2018-06-26 04:02:05

标签: c# .net sql-server entity-framework entity-framework-6

这可能是一个重复的问题,但是大量搜索标题中的单词只会使我得到很多无关的结果。

我有一个大致这样设置的实体:

public abstract class A
{
    public GUID AId { get; set; }

    public string SomeProperty { get; set; }
}

public class B : A
{
    public string SomeOtherProperty { get; set; }
}

上下文中有public DbSet<B> BInstances { get; set; }个对象,B个对象。在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));

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

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

我正在使用EF 6和.NET Framework 4.7.1。

2 个答案:

答案 0 :(得分:2)

谢谢大家的建议-原来这是我引起的映射问题。

在我的OnModelCreating()调用中,我以一种不是从基类继承的类型(当然是MapInheritedProperties()除外)调用了object-这似乎触发了问题。确实共享基类的其他实体在映射调用中也可以正常工作。

我也直接针对实体类调用了ToTable()-由于我不了解的原因,这破坏了我的表映射。将通话移至Map()中后,通话开始按预期运行。

所以我从这里出发:

entity.ToTable("tablename");

对此:

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

解决问题。

希望这对以后的读者有用。

答案 1 :(得分:0)

尝试

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

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