【发布时间】:2017-02-11 16:08:54
【问题描述】:
我正在尝试更新 ProjectModel 中的 ProjectEmployees 集合。 我想删除所有旧值并设置新值。
我的模型:
public class Project
{
...
public ICollection<ProjectEmployee> ProjectEmployees { get; set; }
}
public class ProjectEmployee
{
public int ProjectId { get; set; }
public virtual Project Project { get; set; }
public int UserId { get; set; }
public virtual Employee Employee { get; set; }
}
public class Employee
{
public int UserId { get; set; }
public User User { get; set; }
...
}
public class ProjectGroupModel //ViewModel
{
public int ProjectId { get; set; }
public ICollection<Employee> ProjectEmployees { get; set; }
}
这是典型的多对多关系。
我的控制器操作:
[HttpPost("group")]
public async Task<IActionResult> CreateGroup([FromBody] ProjectGroupModel pro)
{
var dbProject = await _context.Project
.Include(p=>p.ProjectEmployees)
.FirstAsync(p => p.ProjectId == pro.ProjectId);
dbProject.ProjectEmployees.Clear();
foreach (var emp in pro.ProjectEmployees)
{
dbProject.ProjectEmployees.Add(new ProjectEmployee()
{
UserId = emp.UserId
});
}
await _context.SaveChangesAsync();
return Ok();
}
当 pro.ProjectEmployees 为空时,来自 dbProject.ProjectEmployees 的所有记录都已正确删除,如果 dbProject.ProjectEmployees 为空,则添加了模型中的新记录,但当 dbProject.ProjectEmployees 不为空时,我无法设置新记录:
错误:
"无法跟踪实体类型'ProjectEmployee'的实例 因为另一个具有相同键的这种类型的实例已经 被跟踪。添加新实体时,对于大多数键类型,一个唯一的 如果没有设置键(即如果键 属性被赋予其类型的默认值)。如果你是 为新实体显式设置键值,确保它们不会 与现有实体或为其他生成的临时值发生冲突 新实体。附加现有实体时,确保只有一个 具有给定键值的实体实例附加到上下文。"
我试图用数百种方式修复这个动作,但总是……是错误的。
【问题讨论】:
-
应该使用 ToList 方法将 dbProject 转换为列表。然后尝试更新它
-
在我看来像是主键冲突。当您创建新的 ProjectEmployee() 时,您只需设置 UserId。你不应该也设置ProjectId吗?
-
ProjectEmployee的 PK 是什么? -
@MuhammadNasir 我正在获取 Project 的一条记录,我应该在哪里使用 ToList() ?
-
@JakubRusilko 我不这么认为,正如我所说,当 dbProject.ProjectEmployees 为空时,会正确添加新记录。
标签: c# entity-framework asp.net-core entity-framework-core