这可能是一个重复的问题,但是大量搜索标题中的单词只会使我得到很多无关的结果。
我有一个大致这样设置的实体:
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。
答案 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实例(如果已添加)。