【发布时间】:2018-06-26 04:02:04
【问题描述】:
这可能是一个重复的问题,但大量搜索标题中的单词只会让我得到很多不相关的结果。
我有一个大致这样设置的实体:
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。
【问题讨论】:
-
如果你能分享minimal reproducible example,那就太棒了。发生这种情况的原因有几个,完整的端到端示例将为我们指明正确的方向。
-
@mjwills 我会试试,但只能在早上做(这里是深夜)。我的真实代码有点长,并且在 NDA 之下,所以我必须把一些东西放在一起。我花了过去 4-5 个小时试图了解它失败的原因。
-
您能否发布您如何在
OnModelCreating方法中定义实体B映射? -
@user1672994 我会在早上发布它 - 我需要睡觉,我只是最后一次签到。
-
我会除了不是这个实体造成问题(除非代码中的某些地方实际上将条目的状态设置为已添加),而是导航属性。也可能是提供商的问题,但这不太可能。如果没有可验证的示例,这只是一个猜测。
标签: c# .net sql-server entity-framework entity-framework-6