我的Web应用程序在Station
和Timetable
实体之间有多对多链接,链接它们的实体称为StationTimetable
,它还包含有关链接的数据两个实体之间。当我创建新的Timetable
时,我想在数据库中创建新的(和多个)StationTimetable
条目以对应这个新的Timetable
。
到目前为止,当用户创建新的时间表时,我设法让应用程序只保存一个StationTimetable
条目。我有点理解为什么会这样,而且我试图修改它以保存多个条目,但是我现在正在知道这个砖墙。
所以,我有一个TimetablesCreateViewModel
,这是我的视图使用的模型:
public class TimetablesCreateViewModel
{
public Timetable Timetable { get; set; }
public IEnumerable<StationTimetable> StationTimetables { get; set; }
public Station Station { get; set; }
public SelectList StationList { get; set; }
}
在我看来,我让用户最多插入10个StationTimetable
条目:
@for (var i = 0; i < 10; i++)
{
<tr>
<td>@Html.DropDownListFor(model => model.StationTimetables.StationId, Model.StationList, "---", htmlAttributes: new { @class = "form-control col-md-2" })</td>
<td>@Html.EditorFor(model => model.StationTimetables.Arrival, new { htmlAttributes = new { @class = "form-control" } })</td>
<td>@Html.EditorFor(model => model.StationTimetables.Departure, new { htmlAttributes = new { @class = "form-control" } })</td>
</tr>
}
然后,在我的控制器方法中,我想做类似以下的事情:
public ActionResult Create(TimetablesCreateViewModel viewModel)
{
if (ModelState.IsValid)
{
db.Timetables.Add(viewModel.Timetable);
// Somehow loop over viewModel.StationTimetables and add them here?
// db.StationTimetables.Add(viewModel.StationTimetable);
db.SaveChanges();
return RedirectToAction("Index");
}
return View(viewModel);
}
直接问题似乎是我的视图中的DropDownListFor
和EditorFor
方法都在抱怨,这是有意义的,因为我在视图模型中指定StationTimetables
为{ {1}},我无法访问IEnumerable
的{{1}},StationId
和Arrival
属性。这些属性是Departure
持有的实体的一部分。
不幸的是,我不知道如何使用IEnumerable
帮助程序创建一个表单,我可以使用多个IEnumerable
实体填充Html
。如果我可以在我的StationTimetables
方法中获得多个StationTimetable
条目,那么我认为在此之后将它们添加到数据库中会有问题。
感谢您的帮助。
答案 0 :(得分:0)
您需要创建StationTimetables
属性IList
并使用索引器,以便正确命名属性并在回发后绑定
@for (var i = 0; i < 10; i++)
{
<tr>
<td>@Html.DropDownListFor(m => m.StationTimetables[i].StationId, Model.StationList, "---", htmlAttributes: new { @class = "form-control col-md-2" })</td>
<td>@Html.EditorFor(m => m.StationTimetables[i].Arrival, new { htmlAttributes = new { @class = "form-control" } })</td>
<td>@Html.EditorFor(m => m.StationTimetables[i].Departure, new { htmlAttributes = new { @class = "form-control" } })</td>
</tr>
}
这将生成正确的名称属性,例如
<input name="StationTimetables[0].StationId" ...>
<input name="StationTimetables[1].StationId" ...>
如果您无法从IEnumerable
更改,则可以为EditorTemplate
StationTimetable
查看/共享/ EditorTemplates / StationTimetable.cshtml
@model YourAssembly.StationTimetable
<tr>
<td>@Html.DropDownListFor(m => m.StationId, (SelectList)ViewData["StationList"], "---", new { @class = "form-control col-md-2" })</td>
<td>@Html.EditorFor(m => m.Arrival, new { htmlAttributes = new { @class = "form-control" } })</td>
<td>@Html.EditorFor(m => m.Departure, new { htmlAttributes = new { @class = "form-control" } })</td>
</tr>
然后在主视图中
@EditorFor(m => m.StationTimetables, new { StationList = Model.Model.StationList })
这种方法意味着在将模型传递给视图之前,需要在控制器中初始化具有10个项目的StationTimetables
属性。
在任何情况下,由于在EditorFor()
循环中使用DropDownListFor()
的错误(已报告但尚未解决),我建议您使用for
方法。
但是我怀疑你并不总是有10个电台时间表(我让用户插入向上到10 )方法不灵活 - 例如,如果您向属性添加验证属性,除非填写所有10个时间表属性,否则模型将无效。最好使用javascript或BeginCollectionItem帮助程序动态添加新的时间表。这两种方法的示例都包含在this answer
中