首页 > 解决方案 > EF 6 调用 INSERT 而不是 UPDATE

问题描述

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

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

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。

标签: c#.netsql-serverentity-frameworkentity-framework-6

解决方案


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

在我的OnModelCreating()通话中,我调用MapInheritedProperties()了一个没有从基类继承的类型(object当然,除了 之外)——这似乎引发了一个问题。共享基类的其他实体在映射调用中工作得很好。

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

所以我从这个出发:

entity.ToTable("tablename");

对此:

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

解决问题。

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


推荐阅读