Корректный способ отредактировать и обновить комплекс viewmodel объекты с помощью asp.net-mvc2 и платформа объекта

У меня есть таблица в моей базе данных со связью "один ко многим" к другой таблице, которая имеет отношения к третьей таблице:

ParentObject

  • Идентификатор
  • Имя:
  • Описание

ChildObject

  • Идентификатор
  • Имя:
  • Описание
  • ParentObjectID
  • AnotherObjectID

AnotherObject

  • Идентификатор
  • Имя:

Объекты отображаются в Платформу Объекта и выставляются через класс доступа к данным.

Казалось, что ViewModels рекомендуют, когда данные, которые будут отображены значительно, отличаются от объекта области, таким образом, я создал ViewModel следующим образом:

public class ViewModel {
    public IList ParentObjects { get; set; }
    public ParentObject selectedObject { get; set; }
    public IList ChildObjects { get; set; }
}

У меня есть представление, которое отображает список ParentObjects и при нажатии позволит ChildObject быть измененным сохраненный.

<% using (Html.BeginForm()) { %> 

    <% foreach (var parent in Model.ParentObjects) { %>
    
    <% } %>
ObjectID [<%= Html.Encode(parent.ID)%>] <%= Html.Encode(parent.Name)%> <%= Html.Encode(parent.Description)%>
<% if (Model.ParentObject != null) { %>
Name:
<%= Html.TextBoxFor(model => model.ParentObject.Name) %> <%= Html.ValidationMessageFor(model => model.ParentObject.Name, "*")%>
Description:
<%= Html.TextBoxFor(model => model.ParentObject.Description) %> <%= Html.ValidationMessageFor(model => model.ParentObject.Description, "*")%>
Child Objects
<% for (int i = 0; i < Model.ParentObject.ChildObjects.Count(); i++) { %>
<%= Html.DisplayTextFor(sd => sd.ChildObjects[i].Name) %>
<%= Html.HiddenFor(sd => sd.ChildObjects[i].ID )%> <%= Html.TextBoxFor( sd => sd.ChildObjects[i].Description) %> <%= Html.ValidationMessageFor(sd => sd.ChildObjects[i].Description, "*") %>
<% } } } %>

Это все хорошо работает. Мой вопрос вокруг лучшего способа обновить объекты EF и сохранить изменения назад в базе данных. Я первоначально попробовал:

[HttpPost]
    public ActionResult Edit(ViewModel viewModel) {
        ParentObject parent = myRepository.GetParentObjectByID(viewModel.SelectedObject.ID);

        if ((!ModelState.IsValid)
            || !TryUpdateModel(parent, "SelectedObject", new[] { "Name", "Description" })) {
            || !TryUpdateModel(parent.ChildObjects, "ChildObjects", new[] { "Name", "Description" })) {


            //Code to handle failure and return the current model snipped

            return View(viewModel);
        }

        myRepository.Save();

        return RedirectToAction("Edit");
    }

Когда я пытаюсь сохранить изменение в дочернем объекте, я получаю это исключение: Объекты в 'MyEntities. ChildObject' участвуют в отношениях 'FK_ChildObject_AnotherObject'. 0 связанных 'AnotherObject' были найдены. 1 'AnotherObject' ожидается.

Расследование на StackOverflow и общий поиск с помощью Google привели меня к этому сообщению в блоге, которое, кажется, описывает мою проблему: TryUpdateModel () правильно не обрабатывает вложенные наборы. По-видимому, (и ступающий через отладчик подтверждает это) он создает новый ChildObject вместо того, чтобы связаться с объектами EF от моего инстанцированного контекста.

Моя работа hacky вокруг - это:

if (viewModel.ChildObjects.Count > 0) {
    foreach (ChildObject modelChildObject in viewModel.ChildObjects) {
        ChildObject childToUpdate = ParentObject.ChildObject.Where(a => a.ID == modelChildObject.ID).First();
        childToUpdate.Name = modelChildObject.Name;
    }
}

Это, кажется, хорошо работает. Мой вопрос Вам хорошие люди: существует ли корректный способ сделать это? Я попробовал после предложения за то, что сделал пользовательский образцовый редактор связей на ссылку блога, которую я отправил выше, но это не работало (была проблема с отражением, код ожидал, что определенные свойства будут существовать), и я должен был получить что-то идущее как можно скорее.

PS - Я попробовал к очистке код для сокрытия определенной информации, поэтому остерегайтесь, я, возможно, полил из шланга что-то. Я главным образом просто хочу знать, решили ли другие люди эту проблему.

8
задан jslatts 5 April 2010 в 14:38
поделиться

1 ответ

Кратко посмотрим на ошибку с упоминанием FK_ChildObject_AnotherObject ... вы уверены, что в вашей модели данных EF, касающейся AnotherObject, все правильно?

В вашем вопросе вы указываете только две таблицы, но эта ошибка указывает на то, что ChildObject участвует в отношении 1 к * с AnotherObject, и что ни одна из них не присутствует в сущности при сохранении, вызывающей ошибку.

Попробуйте удалить AnotherObject из ситуации, чтобы проверить любые предполагаемые проблемы между ParentObject и ChildObject, или попробуйте изменить отношение FK_ChildObject_AnotherObject с 0..1 на * на короткое время для тестирования.

1
ответ дан 6 December 2019 в 02:24
поделиться
Другие вопросы по тегам:

Похожие вопросы: