如果同一实体包含在实体的不同集合中,如何更改实体的状态



我正在尝试插入一个名为文档的新实体:

public class Document
{
public int Id { get; set; }    
public virtual ICollection<User> UsersOne { get; set; }
public virtual ICollection<User> UsersTwo { get; set; }
}

实体文档与实体用户具有两种多对多关系:

public class User
{
public int Id { get; set; }
[Required]
public string Email { get; set; }
[Required]
public string Password { get; set; }
}

在我的请求中,我发送以下 Json:

{
"UsersOne": [{"Id": 1},{"Id": 2},{"Id": 3}],
"UsersTwo": [{"Id": 1},{"Id": 2},{"Id": 3}],
"Id": 0 
}

问题是我在上下文中有用户,当我在上下文中添加实体文档时_context.Document.Add(entity);,实体将用户插入具有添加状态的上下文中。

也许一种解决方案是更改不变的状态:

foreach (var user in entity.UsersOne)
_context.Entry(user).State = EntityState.Unchanged;
foreach (var user in entity.UsersTwo)
_context.Entry(user).State = EntityState.Unchanged;

但是当我这样做时,我有以下错误

保存或接受更改失败,因为"Entity.User"类型的多个实体具有相同的主键值。确保显式设置的主键值是唯一的。

我还尝试将两个集合合并为一个集合,并更改它们的状态,但上下文中仍然有添加了状态的用户。

在将文档添加到上下文之前,我还尝试将用户状态更改为已分离,但是在_context.SaveChangesAsync();,抛出类型为"System.Data.Entity.Validation.DbEntityValidationException"的异常,因为属性电子邮件和密码是用户所必需的。

您有两个选择:

如果要创建 User 实体并将其添加到两个
  1. 不同的列表,则必须先创建并保存 User 实体,然后返回并将新创建的用户添加到两个列表中。

  2. 反序列化 JSON 时,必须创建单个 User 实体并将同一实例添加到两个集合。 否则,EF 将认为它们是具有相同 PK 的两个不同用户实体,并引发该异常。 如果将同一实例添加到两者,EF 应识别它是同一用户并正确保存。

最后,如果您仅使用 ID 保存此 User 实体,您将在电子邮件和密码上收到所需的错误,因为您那里有 [必需] 注释。

最新更新