我试图插入名为Document的新实体:
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;
但是当我这样做时,我有以下错误
保存或接受更改失败,因为多个实体的类型为&#39; Entity.User&#39;具有相同的主键值。确保显式设置的主键值是唯一的。
我还尝试将两个集合合并为一个,并更改其状态,但上下文仍然具有添加状态的用户。
我还尝试将用户状态更改为已分离,然后将文档添加到上下文中,但在_context.SaveChangesAsync();
上,类型为&#39; System.Data.Entity.Validation.DbEntityValidationException&#39;抛出,因为用户需要属性电子邮件和密码。
答案 0 :(得分:0)
您有两种选择:
如果正在创建用户实体并将其添加到两个不同的列表中,则必须先自行创建并保存用户实体,然后返回并将新创建的用户添加到两个列表中。
反序列化JSON时,必须创建单个User实体并将同一实例添加到两个集合中。否则,EF会认为它们是具有相同PK的两个不同的用户实体并抛出该异常。如果您向两者添加相同的实例,EF应该识别它是相同的用户并正确保存。
最后,如果您只使用Id保存此User实体,您将在Email和Password上获得所需的错误,因为那里有[Required]注释。