我很难使用EF Code-first更新和删除多对多关系。
我的模型相当简单:
public class Issue
{
[Key]
public int IssueId { get; set; }
public int Number { get; set; }
public string Title { get; set; }
public DateTime Date { get; set; }
public virtual ICollection<Creator> Creators { get; set; }
}
public class Creator
{
[Key]
public int CreatorId { get; set; }
public string FirstName { get; set; }
public string MiddleName { get; set; }
public string LastName { get; set; }
public virtual ICollection<Issue> Issues { get; set; }
}
public class Icbd : DbContext
{
public DbSet<Issue> Issues { get; set; }
public DbSet<Creator> Creators { get; set; }
}
我一直不知道如何使用EF上下文来更新多对多关系。在我的插入/更新操作中,我有这段代码:
[HttpPost]
public ActionResult EditIssue ( Issue issue, int[] CreatorIds )
{
if(CreatorIds == null)
ModelState.AddModelError("CreatorIds", "Please specify at least one creator");
if(ModelState.IsValid)
{
// insert or update the issue record (no relationship)
if (issue.IssueId == 0)
db.Issues.Add(issue);
else
db.Entry(issue).State = System.Data.EntityState.Modified;
db.SaveChanges();
// delete - delete current relationships
if (issue.Creators != null)
{
issue.Creators = new List<Creator>();
db.Entry(issue).State = System.Data.EntityState.Modified;
db.SaveChanges();
}
// insert - get creators for many-to-many realtionship
issue.Creators = db.Creators.Where(x => CreatorIds.Contains(x.CreatorId)).ToList();
db.Entry(issue).State = System.Data.EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
IssueEditModel issueEdit = new IssueEditModel{
Creators = db.Creators.ToList(),
Issue = issue,
};
return View(issueEdit);
}
我可以插入 Issues
,也可以插入新的 issue.Creators
,但是当我尝试删除当前的issue.Creators
以便插入新的时,issue.Creators
总是为 null,因此它永远不会更新为空列表。我不明白这个问题。issue.Creators
中有记录,因为当代码继续插入新的创建者时,我会得到如下错误:
Violation of PRIMARY KEY constraint 'PK__CreatorI__13D353AB03317E3D'. Cannot insert duplicate key in object 'dbo.CreatorIssues'.
The statement has been terminated.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.Data.SqlClient.SqlException: Violation of PRIMARY KEY constraint 'PK__CreatorI__13D353AB03317E3D'. Cannot insert duplicate key in object 'dbo.CreatorIssues'.
The statement has been terminated.
Source Error:
Line 59: issue.Creators = db.Creators.Where(x => CreatorIds.Contains(x.CreatorId)).ToList();
Line 60: db.Entry(issue).State = System.Data.EntityState.Modified;
Line 61: db.SaveChanges();
Line 62:
Line 63: return RedirectToAction("Index");
我该如何使issue.Creators
准确显示当前关系,以便我可以删除它们?
更新:工作控制器
[HttpPost]
public ActionResult EditIssue ( Issue issue, int[] CreatorIds )
{
if(CreatorIds == null)
ModelState.AddModelError("CreatorIds", "Please specify at least one creator");
if(ModelState.IsValid)
{
// insert or update the issue record (no relationship)
if (issue.IssueId == 0)
db.Issues.Add(issue);
else
db.Entry(issue).State = System.Data.EntityState.Modified;
db.SaveChanges();
// insert and update many to many relationship
issue = db.Issues.Include("Creators").Where(x => x.IssueId == issue.IssueId).Single();
issue.Creators = db.Creators.Where(x => CreatorIds.Contains(x.CreatorId)).ToList();
db.Entry(issue).State = System.Data.EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
IssueEditModel issueEdit = new IssueEditModel{
Creators = db.Creators.ToList(),
Issue = issue,
};
return View(issueEdit);
}