我环顾了几个小时,但我似乎无法找到解决问题的直接方法。
基本上,我有一对多的关系,与桌子联系在一起。我的控制器似乎完美地处理'create'方法,在'1'表和桥接'many'表中创建记录。
但是,'edit'方法似乎根本不修改/更新桥接表。关于我做错了什么的想法,以及为什么它与'创造'方法不同?
为简洁起见,我想说我有以下型号:
public class Incident
{
[Key]
public int IncidentID { get; set; }
public string Title { get; set; }
public virtual ICollection<IncidentResources> Resources{ get; set; }
}
资源模型:
public class Resource
{
[Key]
public int ResourceID{ get; set; }
public int Name { get; set; }
...OTHER FIELDS REMOVED FOR BREVITY...
}
我正在通过桥接表和模型来连接这两个:
public class IncidentResource
{
[Key]
public int IncidentResourceID { get; set; }
public int IncidentID { get; set; }
public int ResourceID { get; set; }
public virtual <Resource> Resource { get; set; }
}
在我的控制器中,我有以下代码:
[HttpPost]
public ActionResult Create(Incident incident)
{
//incident.Resources is returned as a valid object...
if (ModelState.IsValid)
{
db.Incidents.Add(incident);
db.SaveChanges();
return RedirectToAction("Index");
}
return View(incident);
}
以上作品完美无缺!正如我所提到的,新事件被插入到正确的表中,并且分配给事件的所有资源都被添加到IncidentResources表中。
但是,以下代码不适用于编辑...
[HttpPost]
public ActionResult Edit(Incident incident)
{
if (ModelState.IsValid)
{
//THE USER CAN ADD ADDITIONAL RESOURCES
foreach (IncidentResource r in incident.Resources)
{
r.IncidentID = incident.IncidentID;
}
db.Entry(incident).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
return View(incident);
}
同样,上面似乎对IncidentResources表没有任何作用。不会添加,删除或更新记录。我也没有收到错误。它只是没有做任何事情。
请注意,我不想删除桥表数据并重新插入。我将与那些我不想孤儿的数据建立一对多的关系。
我不了解这是如何运作的?
答案 0 :(得分:1)
您需要附加在EF外部创建的实体实例,并让EF知道它已被修改。
尝试添加:
db.Incidents.Attach(incident);
在改变状态之前。在您的情况下,您的最后一段代码应如下所示:
[HttpPost]
public ActionResult Edit(Incident incident)
{
if (ModelState.IsValid)
{
//THE USER CAN ADD ADDITIONAL RESOURCES
foreach (IncidentResource r in incident.Resources)
{
r.IncidentID = incident.IncidentID;
}
db.Incidents.Attach(incident);
db.Entry(incident).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
return View(incident);
}
答案 1 :(得分:0)
似乎IncidentResource对象中的IncidentID未映射为Incident表的外键。尝试添加ForeignKey注释以将IncidentID显式设置为指向Incident:
的外键 [ForeignKey("Incident")]
public int IncidentID { get; set; }
答案 2 :(得分:0)
我想知道,在您当前的代码中,实体框架是否发现事件对象根本没有被更改,并且没有尝试查看是否有需要调整的IncidentResources。
尝试在循环中添加以下行:
db.Entry(r).State = EntityState.Modified;
答案 3 :(得分:0)
除非您在表单中的隐藏字段中跟踪IncidentID,否则我打赌问题源于它尝试更新不存在的事件(IncidentID:0)
这将取决于您的路线,但假设默认路线模式:
[HttpPost]
public ActionResult Edit(int id, Incident incident)
{
incident.IncidentID = id;
if (ModelState.IsValid)
{
//THE USER CAN ADD ADDITIONAL RESOURCES
foreach (IncidentResource r in incident.Resources)
{
r.IncidentID = incident.IncidentID;
}
db.Entry(incident).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
return View(incident);
}
答案 4 :(得分:0)
如果可以,您可以尝试将IncidentResource表的外键IncidentID添加到主键以生成复合主键。我遇到了类似的问题,这对我有帮助。
我从其他一些stackoverflow问题中得到了解决方案。我的设置与这些完全不匹配,因为我使用AutoMapper和Entity模型的第一个工作单元方法,但是在关系表上使用复合键修复了我的问题。
Is it possible to remove child from collection and resolve issues on SaveChanges?
What's the difference between identifying and non-identifying relationships?
答案 5 :(得分:0)
你不应该做以下
[HttpPost]
public ActionResult Edit(Incident incident)
{
if (ModelState.IsValid)
{
//THE USER CAN ADD ADDITIONAL RESOURCES
foreach (IncidentResource r in incident.Resources)
{
r.IncidentID = incident.IncidentID;
db.Entry(r).State = EntityState.Modified;
}
db.SaveChanges();
return RedirectToAction("Index");
}
return View(incident);
}