qua*_*els 6 database asp.net entity-framework entity-framework-4.1
我很难用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; }
}
Run Code Online (Sandbox Code Playgroud)
我一直无法弄清楚如何使用EF上下文更新多对多的实现.在我的isnert/update操作中,我有以下代码:
[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);
}
Run Code Online (Sandbox Code Playgroud)
我可以插入Issues
,我可以插入新的issue.Creators
没有问题.但是,当我试图删除当前,issue.Creators
所以我可以插入新的,issue.Creators
总是为空,所以它永远不会更新为空列表.我不明白这一点.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");
Run Code Online (Sandbox Code Playgroud)
如何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);
}
Run Code Online (Sandbox Code Playgroud)
模型绑定器不会为您加载它们 - 来自视图的问题对象不会神奇地包含它们,除非您正确设置了绑定的所有内容。
如果没有看到您的视图,人们无法说出原因,但足以说明您必须加载它们,然后删除它们。您可以加载新的 issues 对象,然后执行 TryUpdateModel(issues) 将表单值更新到该模型中。然后删除每个 issues.Creators(如果这是预期的操作)
if(ModelState.IsValid)
{
var issueFromDb = db.Issues.Where(x => criteria here);
bool updateSuccessful = TryUpdateModel(issueFromDb);
foreach(var creator in issueFromDb.Creators)
{
//delete creator if thats what you want
}
但是,如果您只是希望所有创建者从页面返回而不加载,请检查绑定到可枚举。有很多关于此的帖子,这里是一篇:ASP.NET MVC3 Model Binding using IEnumerable (Cannot infer type from)
如果存在这种关系,创建者应该通过加载问题来自动加载。您不需要仅加载创建者。加载您的完整模型以确保其正常工作,就像我在上面的编辑中所做的那样。您的代码“应该”工作正常,但您可能需要 .Include("Creators") 尝试以下操作:
var testIssue = from o in db.Issues.Include("Creators") 其中 o.IssueId == issues.IssueId 选择o; foreach(testIssue.Creators 中的 var 创建者) { //检查创建者 }
这会让您知道“Creators”是否正确加载。
归档时间: |
|
查看次数: |
2207 次 |
最近记录: |