Asp.net mvc 2 使用MVC2存储库Viewmodel模式更新EF4中的外键列表

Asp.net mvc 2 使用MVC2存储库Viewmodel模式更新EF4中的外键列表,asp.net-mvc-2,entity-framework-4,Asp.net Mvc 2,Entity Framework 4,好的,我真的很难在MVC2/EF4中更新外键列表。 我在一个模板对象之间有一个一对多的关系,这个模板对象可以有很多或者没有TemplateScenario对象 本质上,我在控制器中有一个编辑方法,它正试图做到这一点: // POST: /Modes/Edit/1 [HttpPost] public ActionResult Edit(int id, FormCollection formValues) { Template

好的,我真的很难在MVC2/EF4中更新外键列表。 我在一个模板对象之间有一个一对多的关系,这个模板对象可以有很多或者没有TemplateScenario对象

本质上,我在控制器中有一个编辑方法,它正试图做到这一点:

// 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对象已经存在,并且我尝试根据新列表更新它们,则会出现以下错误:

“操作失败:无法更改关系,因为一个或多个 的外键属性不可为空。当对 关系,相关外键属性设置为空值。如果 外键不支持空值,必须定义新关系, 必须为外键属性分配另一个非空值,或 必须删除不相关的对象。“

_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);
            }
        }

    }
公共作废更新(模板模板、IList模板场景)
{
//删除旧条目
foreach(实体中的TemplateScenario ts.TemplateScenarios)
{
if(ts.TemplateID==template.TemplateID)
{
if(templateScenarios==null)
entities.TemplateScenarios.DeleteObject(ts);
如果(!templateScenarios.Where(tsl=>tsl==ts.ScenarioID).Any())
entities.TemplateScenarios.DeleteObject(ts);
}
}
//如果它们为null,则不需要添加任何内容。
if(templateScenarios==null)
返回;
//添加新条目
foreach(模板场景中的int ts)
{
如果(!entities.TemplateScenarios.Where(tsc=>tsc.ScenarioID==ts&&tsc.TemplateID==template.TemplateID).Any())
{
TemplateScenario TempsceneToAdd=新的TemplateScenario();
tempsentoadd.ScenarioID=ts;
tempScenToAdd.TemplateID=template.TemplateID;
entities.TemplateScenarios.AddObject(TempSceneToAdd);
}
}
}
但这让我感觉很肮脏,我想我已经接近了第一种更自动的方法。我在互联网上搜索了一下,在stackoverflow上找到了一些类似的帖子,但我发现很难达到那个“啊哈”的时刻

谢谢


汤姆。

顺便说一句,我解决了我的问题

问题是我的联接表错误地使用了它自己的主键,而不是使用基于两个外键的复合键。这显然是错误的/糟糕的做法,EF4和UpdateModel()的效果并不好


我从一位前同事那里继承了DB设计,因此我认为DB设计是正确的,没有过多考虑它。我知道,我太笨了。

你知道为什么特定的数据库设计会导致这个问题吗?为什么表在组合上使用自己的主键时会引起问题?