C# 实体框架上下文自动创建新实体

C# 实体框架上下文自动创建新实体,c#,.net,entity-framework,C#,.net,Entity Framework,我有一个EF Code First数据库,在数据库中创建实体之前,我首先检查是否存在相关实体,将其关联,然后创建实体 例如,假设我有一个订单实体,它有一个相关的用户实体。如果订单实体想要存储在数据库中,我首先检查用户是否已经存在。如果是,我希望更改顺序,使其用户属性等于现有用户实体,而不是创建新记录 // check for an existing user and associate them instead of creating a new one var existingUser = a

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

例如,假设我有一个订单实体,它有一个相关的用户实体。如果订单实体想要存储在数据库中,我首先检查用户是否已经存在。如果是,我希望更改顺序,使其用户属性等于现有用户实体,而不是创建新记录

// 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属性,而不是在上下文中创建新记录?

多亏了GertArnold,我能够通过执行以下操作来解决此问题:

替换:

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

参考:

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


多亏了GertArnold,我可以通过以下方式解决这个问题:

替换:

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

参考:

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


你能把你的用户类的定义和订单的用户属性放在一起吗?你发布的代码在哪一类?(即OrderRepository?)您的UserRepository和此代码是否共享相同的DbContext引用?我怀疑这可能是2个dbContexts与一个映射相结合的情况,其中PK没有正确设置,因此顺序。用户被视为一个新实体。如果PK设置为最小值,您可能会在尝试插入已存在的记录时收到重复的PK。此时,
顺序
的状态是什么?我认为你应该展示更多的周边代码。还有,你为什么不直接附加
order.User而不是替换它呢?@GertArnold你真是个天才!我已经被困在这个问题上一段时间了,你的评论围绕着附件而不是替换作品。将此用作您的建议的参考:您能否提供用户类的定义以及订单的用户属性?你发布的代码在哪一类?(即OrderRepository?)您的UserRepository和此代码是否共享相同的DbContext引用?我怀疑这可能是2个dbContexts与一个映射相结合的情况,其中PK没有正确设置,因此顺序。用户被视为一个新实体。如果PK设置为最小值,您可能会在尝试插入已存在的记录时收到重复的PK。此时,
顺序
的状态是什么?我认为你应该展示更多的周边代码。还有,你为什么不直接附加
order.User而不是替换它呢?@GertArnold你真是个天才!我已经被困在这个问题上一段时间了,你的评论围绕着附件而不是替换作品。将此作为您建议的参考: