使用MVC 2 Repository Viewmodel Pattern更新EF4中的外键列表 [英] Updating a list of foreign keys in EF4, using MVC 2 Repository Viewmodel Pattern

查看:206
本文介绍了使用MVC 2 Repository Viewmodel Pattern更新EF4中的外键列表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

好吧,我真的很努力地在MVC2 / EF4中更新外键列表。
我有一个可以拥有很多或没有TemplateScenario对象的Template对象之间的一对多关系。



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

  // POST:/模式/编辑/ 1 
[HttpPost]
public ActionResult Edit(int id,FormCollection formValues)
{
模板模板= _templateRepository.GetTemplate(id);

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

//更新模型
UpdateModel(viewModel);
UpdateModel(viewModel.Template.TemplateScenarios,TemplateScenarioList,new [] {ScenarioID,TemplateID});

_templateRepository.Save();

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

}

此代码成功更新模板对象。它还会添加templatescenario子对象,但只有当我第一次将templatescenarios添加到此特定模板时。如果给定模板已存在任何templatescenario对象,并且我尝试根据新列表更新它们,我会收到以下错误:


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


_templateRepository.Save();只是调用了实体.saveChanges()EF4方法。



我可以通过将自定义更新方法的templatesCenario ids列表传递给我的存储库类来解决这个问题,如下所示:

  public void Update(模板模板,IList< int> templateScenarios)
{

//删除旧条目
foreach(templatesScenario 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);
}
}

//如果它们为空,则不需要添加任何内容。
if(templateScenarios == null)
return;

//添加新条目
foreach(templateScenarios中的int ts)
{
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);
}
}

}

但是感觉很脏,我觉得我和第一个更自动的方法非常接近。我已经在互联网上找到了一些类似的帖子,但发现很难达到这个哈哈的时刻。



谢谢,



Tom。

解决方案

偶然地,我整理了我的问题。



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



我从一个前同伴继承了DB设计,因此已经采取了db设计是正确的,没有太多的思考。非常愚蠢的我,我知道。


Okay, I'm really struggling with how to update a list of foreign keys in MVC2/EF4. I have a one to many relationship between a Template object which can have many or no TemplateScenario objects.

Essentially, I have an edit method in a controller that is trying to do this:

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

        }

This code successfully updates the 'template' object. It also adds the 'templatescenario' child objects BUT only if it is the first time I have added 'templatescenarios' to this particular template. If any templatescenario objects already exist for a given template, and I try to update them based on the new list, I get this error:

"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."

The _templateRepository.Save(); is just calling the entities.SaveChanges() EF4 method.

I can solve this in a dirty way by passing down a list of templatescenario ids to my repository class in a custom 'update' method that looks like this:

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

    }

But that just feels dirty and I think I'm so close with the first, more automatic method. I've scoured the internet and found some similar posts on stackoverflow but am finding it difficult to reach that 'aha' moment.

Thanks,

Tom.

解决方案

Incidently, I sorted out my problem.

The problem was my joining table was incorrectly using it's own primary key instead of using a composite key based on two foreign keys. This is obviously wrong /bad practice and EF4 and UpdateModel() don't play nice.

I had inherited the DB design from an ex-collegue and thus had taken the db design as correct without thinking too much about it. Very stupid of me, I know.

这篇关于使用MVC 2 Repository Viewmodel Pattern更新EF4中的外键列表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆