【问题标题】:Entity Framework context automatically creating new entity实体框架上下文自动创建新实体
【发布时间】:2017-06-30 06:38:52
【问题描述】:

我有一个 EF Code First 数据库,在我在数据库中创建实体之前,我先检查相关实体是否存在,关联它,然后创建实体。

例如,假设我有一个 Order 实体,它有一个相关的 User 实体。如果 Order 实体想要存储在数据库中,我首先检查 User 是否已经存在。如果是这样,我想更改 Order 以使其 User 属性等于现有的 User 实体,而不是创建新记录。

// check for an existing user and associate them instead of creating a new one
var existingUser = await _userRepository.GetAsync(u => u.Username == order.User.Username);
if (existingUser != null)
{
    order.User = existingUser;
    Context.Entry(order.User).State = EntityState.Modified;
}

上面代码中的以下行导致了问题:

order.User = existingUser; 

在该行之前,“Context.Users”已有两条记录(正确)。但在那一行之后,它包含三个记录(不正确),其中两个完全相同。

为什么代码不简单地将 existingUser 对象分配给 order.User 属性,而是在 Context 中创建新记录?

【问题讨论】:

  • 你能把你的用户类的定义和订单的用户属性一起列出来吗?您发布的代码在哪个班级? (即 OrderRepository?)您的 UserRepository 和此代码是否共享相同的 DbContext 引用?我怀疑这可能是 2 个 dbContexts 与未正确设置 PK 的映射相结合的情况,因此 order.User 被视为新实体。如果 PK 设置为最低限度,您可能会得到重复的 PK 尝试插入已存在的记录。
  • 此时order 的状态如何?我认为您应该显示更多周围的代码。另外,为什么不直接附上order.User 而不是替换它呢?
  • @GertArnold 你绝对是个天才!我已经坚持了一段时间了,你关于附加而不是替换的评论很漂亮。将此用作您的建议的参考:stackoverflow.com/a/14476027/1448448

标签: c# .net entity-framework


【解决方案1】:

感谢 GertArnold,我能够通过执行以下操作来解决它:

替换:

order.User = existingUser;
Context.Entry(order.User).State = EntityState.Modified;

与:

Context.Entry(order.User).CurrentValues.SetValues(existingUser);

参考: https://stackoverflow.com/a/14476027/1448448

这很可能是因为 oldEntry 和 newEntry 有 实体键的不同值。它可能会失败,因为 您不能更改现有实体的键。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多