使用Entity Framework 4 MVC3显示和保存导航属性

时间:2012-07-11 23:26:24

标签: asp.net-mvc asp.net-mvc-3 entity-framework entity-framework-4

我无法显示和保存导航属性。

我有3张桌子:

RateProfile

  • RateProfileID
  • 摘要名称

  • RateID
  • RateProfileID
  • PanelID
  • 金额

面板

  • PanelID
  • PanelName

我为每个外键的导航属性都有模型(例如RatesRateProfile的导航属性)。我有一个以RateProfile为模型的编辑页面。在此页面上,我有PanelID的下拉列表。下拉过滤器显示了导航属性(每个panelID有28个与之关联的费率)。每当更改下拉列表时,它都会发布到我的Edit方法(在继续之前保存现有数据并显示所选新panelID的费率)。

我只通过ViewBag将所需的费率记录传递给我查看列表。

我最初使用的是foreach循环

foreach(PDR.Models.Rate rate in ViewBag.Rates){
                    @Html.HiddenFor(modelItem => rate.RateProfileID)
                    @Html.HiddenFor(modelItem => rate.RateID)
                    @Html.HiddenFor(modelItem => rate.PanelID)

                    @Html.EditorFor(modelItem => rate.Amount)
                    @Html.ValidationMessageFor(modelItem => rate.Amount)
}

使用foreach循环时,在更改PanelID的下拉列表时,所有内容都会正确显示,即它会以每个面板的正确速率显示。但是,我的模型中没有一个会与我的模型一起传回我的控制器中的HTTPPost Edit方法。传递给我的控制器的RateProfile将在其导航属性中有0条记录(视图中有28条记录)。

我被建议将foreach循环更改为for(int i ...)循环。显然,foreach循环将所有文本框命名为同一个东西,并且常规for循环根据索引命名它们。

使用for(int i ...)循环,Rates导航属性确实在传递给HTTPPost Edit方法时具有所有记录,并且我能够根据我输入的内容更新这些记录。

但是......现在使用for(int i ...)循环,页面将不会显示基于panelID的正确记录(它始终显示默认panelID的记录什么时候改变)甚至更疯狂的是,如果我在我的视图中放置断点,我会看到正确的Rate记录仍然传递给View。我看到正确的RateID / amount等都被放入Html助手中,但是当页面实际显示时,它会显示在更改下拉列表之前的数据而不是正确的数据我正在观看它在调试模式下填充。

这是我从foreach循环切换到正常for循环后使用的视图代码:

    @{List<PDR.Models.Rate> rates = ViewBag.rates;
      var count = rates.Count;
      }
    @for (int i = 0; i < count; i++)
    {
                    @Html.HiddenFor(modelItem => rates[i].RateProfileID)
                    @Html.HiddenFor(modelItem => rates[i].RateID)
                    @Html.HiddenFor(modelItem => rates[i].PanelID)

                    @Html.EditorFor(modelItem => rates[i].Amount)
                    @Html.ValidationMessageFor(modelItem => rates[i].Amount)
    }

通过在我的视图中检查调试模式中的值,我知道正确的费率将根据ViewBag.rates传递给panelID。问题是即使我可以在调试中逐步执行它并观察它为上面的循环中的每个速率为RateID,PanelIDAmount设置了正确的值,页面上实际显示的内容始终是panelID == 1的值,然后传递给我的控制器的值始终是panelID == 1的费率值,而不是我传递给视图的费率。

这是编辑方法的代码。我很确定问题出在视图中,因为rateprofile(应该是我视图中的模型)从来没有得到正确的导航属性。

[HttpPost]
    public ActionResult Edit(RateProfile rateprofile, int panelID)
    {

        var panels = db.Panels;
        ViewBag.PanelDropDown = new SelectList(panels, "PanelID", "PanelName", panelID);
        ViewBag.PanelID = panelID;

        if (ModelState.IsValid)
        {
            db.Entry(rateprofile).State = EntityState.Modified;

            foreach (Rate rate in rateprofile.Rates)
            {
                db.Entry(rate).State = EntityState.Modified;
            }
            db.SaveChanges();
        }
        rateprofile = db.RateProfiles.Include(a => a.Rates).Where(a => a.RateProfileID == rateprofile.RateProfileID).Single(); //reloads the current rateprofile from the db
        PopulatePanelDropDown(rateprofile, panelID); //populates the ViewBag.rates variable

        return View(rateprofile);
    }

总结:

  • foreach循环Rates:根据panelID正确显示所有内容,但不会将值传递给控制器​​。

  • for(int i ...)循环:仅显示panelID == 1的值,不会根据panelID进行更新。将保存,但仅保存与panelID == 1相关联的记录。

1 个答案:

答案 0 :(得分:0)

在搜索了几个星期而没有找到任何对我有用的答案之后,我终于将我的HTTP邮件编辑方法更改为重定向到我的HTTPget编辑方法而不是返回视图。我将RateProfileID和panelID传递给我的HTTPget编辑方法,当面板下拉列表更改时,它现在没有任何问题显示正确的数据。