2010-10-18 55 views
0

好吧,我真的很苦恼如何更新MVC2/EF4中的外键列表。 我有一个模板对象可以有很多或没有TemplateScenario对象之间的一对多关系。使用MVC 2更新EF4中的外键列表存储库Viewmodel模式

从本质上讲,我有一个控制器的编辑方法是试图做到这一点:

// POST: /Modes/Edit/1 
     [HttpPost] 
     public ActionResult Edit(int id, FormCollection formValues) 
     { 
      Template template = _templateRepository.GetTemplate(id); 

      TemplateCreateViewModel viewModel = new TemplateCreateViewModel(); 
      viewModel.Template = template; 
      viewModel.TemplateScenarioList = template.TemplateScenarios.ToList(); 

      //Update the model 
      UpdateModel(viewModel); 
      UpdateModel(viewModel.Template.TemplateScenarios, "TemplateScenarioList", new[] { "ScenarioID", "TemplateID" }); 

      _templateRepository.Save(); 

      return RedirectToAction("Edit", new { id = template.TemplateID }); 

     } 

此代码成功更新了“模板”的对象。它还会添加'templatescenario'子对象,但只有当它是第一次将'templatescenarios'添加到此特定模板时才会添加。如果有任何templatescenario对象已经存在一个给定的模板,我尝试以新的名单上更新它们,我得到这个错误:

"The operation failed: The relationship could not be changed because one or more of the foreign-key properties is non-nullable. When a change is made to a relationship, the related foreign-key property is set to a null value. If the foreign-key does not support null values, a new relationship must be defined, the foreign-key property must be assigned another non-null value, or the unrelated object must be deleted."

的_templateRepository.Save();只是调用entities.SaveChanges()EF4方法。

我可以templatescenario ID列表传递到我的仓库类中的自定义“更新”的方法,看起来像这样在一个肮脏的方式解决这个问题:

public void Update(Template template, IList<int> templateScenarios) 
    { 

     //Delete Old Entries 
     foreach (TemplateScenario ts in entities.TemplateScenarios) 
     { 
      if (ts.TemplateID == template.TemplateID) 
      { 
       if (templateScenarios == null) 
        entities.TemplateScenarios.DeleteObject(ts); 
       else if (!templateScenarios.Where(tsl => tsl == ts.ScenarioID).Any()) 
        entities.TemplateScenarios.DeleteObject(ts); 
      } 
     } 

     //Don't need to add anything if they are null. 
     if (templateScenarios == null) 
      return; 

     //Add New Entries 
     foreach (int ts in templateScenarios) 
     { 
      if (!entities.TemplateScenarios.Where(tsc => tsc.ScenarioID == ts && tsc.TemplateID == template.TemplateID).Any()) 
      { 
       TemplateScenario tempScenToAdd = new TemplateScenario(); 
       tempScenToAdd.ScenarioID = ts; 
       tempScenToAdd.TemplateID = template.TemplateID; 
       entities.TemplateScenarios.AddObject(tempScenToAdd); 
      } 
     } 

    } 

但这只是觉得脏,我认为我与第一个更自动的方法非常接近。我搜索了互联网,在stackoverflow上发现了一些类似的帖子,但是我发现很难达到这个'aha'时刻。

谢谢,

汤姆。

回答

0

可喜的是,我整理了我的问题。

问题是我的连接表错误地使用它自己的主键而不是使用基于两个外键的组合键。这显然是错误的/不好的做法,EF4和UpdateModel()不会很好。

我从一位前同事继承了DB设计,因此把db设计看成是正确的,而没有考虑太多。我知道,我很愚蠢。

+0

你知道为什么特定的数据库设计导致了这个问题吗?为什么在使用自己的主键而不是组合键时,表会引起问题? – Sergio 2011-07-10 22:35:23