Обновление списка внешних ключей в EF4 с использованием шаблона модели репозитория MVC 2 - PullRequest
0 голосов
/ 18 октября 2010

Хорошо, я действительно борюсь с тем, как обновить список внешних ключей в MVC2 / EF4. У меня есть отношение один ко многим между объектом Template, у которого может быть много или нет объектов 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' в этот конкретный шаблон. Если какие-либо объекты шаблонов сценария уже существуют для данного шаблона, и я пытаюсь обновить их на основе нового списка, я получаю эту ошибку:

"Операция не удалась: отношение не может быть изменено, потому что один или несколько из свойств внешнего ключа не обнуляется. Когда изменение сделано в отношение, для свойства внешнего ключа установлено нулевое значение. Если внешний ключ не поддерживает нулевые значения, должны быть определены новые отношения, свойству внешнего ключа должно быть присвоено другое ненулевое значение или несвязанный объект должен быть удален. "

_templateRepository.Save (); это просто вызов метода entity.SaveChanges () EF4.

Я могу решить эту проблему грязным путем, передав список идентификаторов шаблонов сценариев моему классу репозитория с помощью специального метода update, который выглядит следующим образом:

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, но мне трудно достичь этого «ага» момента.

Спасибо

Том.

1 Ответ

0 голосов
/ 27 октября 2010

Кстати, я разобрался с проблемой.

Проблема заключалась в том, что моя таблица присоединения неправильно использовала собственный первичный ключ вместо составного ключа, основанного на двух внешних ключах.Это явно неправильная / плохая практика, и EF4 и UpdateModel () не играют хорошо.

Я унаследовал дизайн БД от бывшего коллеги и, таким образом, принял дизайн БД как правильный, не слишком задумываясь оЭто.Я знаю, очень глупо с моей стороны.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...