簡體   English   中英

使用asp.net-mvc2和實體框架編輯和更新復雜的viewmodel對象的正確方法

[英]Correct way to edit and update complex viewmodel objects using asp.net-mvc2 and entity framework

我的數據庫中有一個表,該表與另一個表具有一對多關系,而另一個表與第三個表有關系:

父對象

  • ID
  • 名稱
  • 描述

子對象

  • ID
  • 名稱
  • 描述
  • ParentObjectID
  • AnotherObjectID

另一個對象

  • ID
  • 名稱

這些對象被映射到Entity Framework中,並通過數據訪問類公開。

當要顯示的數據與域對象有很大差異時,似乎建議使用ViewModels,因此我按如下方式創建了ViewModel:

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

我有一個視圖,該視圖顯示ParentObjects的列表,並且在單擊時將允許保存修改的ChildObject。

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

這一切都很好。 我的問題是圍繞更新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和常規搜索的調查使我轉向了這篇博客文章該文章似乎描述了我的問題:TryUpdateModel()無法正確處理嵌套集合。 顯然,(並逐步通過調試器確認了這一點)它將創建一個新的ChildObject,而不是與我實例化的上下文中的EF對象關聯。

我的變通方法是這樣的:

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-我試圖清理代碼以隱藏特定信息,所以請注意,我可能已經整理了一些東西。 我主要只是想知道其他人是否解決了這個問題。

只是簡單地看一下提到FK_ChildObject_AnotherObject ...的錯誤...您確定在與AnotherObject有關的EF數據模型中所有內容都正確連接了嗎?

在您的問題中,您僅列出了兩個表,但是此錯誤表明ChildObject正在與AnotherObject進行從1到*的關系,並且保存時實體中不存在任何一個,從而導致錯誤。

嘗試從這種情況下刪除AnotherObject以便測試ParentObject和ChildObject之間的任何假定問題,或嘗試將FK_ChildObject_AnotherObject關系從0..1短暫更改為*以進行測試。

您可以看看使用Omu ValueInjector而不是tryupdate。 盡管我更喜歡按慣例使用它,但它可以配置為更加智能。

在這里對原始問題還不完全清楚。 我不確定為什么首先將視圖模型中的子對象與父對象分離?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM