将多个实体插入到多对多链接表中

我的Web应用程序在StationTimetable实体之间具有多对多链接,并且链接它们的实体称为StationTimetable ,它还保存有关两个实体之间链接的数据。 当我创建一个新的Timetable ,我想在数据库中创建新的(和多个) StationTimetable条目以对应这个新的Timetable

到目前为止,我已经设法让应用程序在用户创建新的时间表时只保存一个StationTimetable条目。 我有点理解为什么会这样,并且我试图修改它以保存多个条目,但是我现在正在知道这个砖墙。

所以,我有一个TimetablesCreateViewModel ,它是我的视图使用的模型:

 public class TimetablesCreateViewModel { public Timetable Timetable { get; set; } public IEnumerable StationTimetables { get; set; } public Station Station { get; set; } public SelectList StationList { get; set; } } 

在我看来,我让用户最多插入10个StationTimetable条目:

 @for (var i = 0; i < 10; i++) {  @Html.DropDownListFor(model => model.StationTimetables.StationId, Model.StationList, "---", htmlAttributes: new { @class = "form-control col-md-2" }) @Html.EditorFor(model => model.StationTimetables.Arrival, new { htmlAttributes = new { @class = "form-control" } }) @Html.EditorFor(model => model.StationTimetables.Departure, new { htmlAttributes = new { @class = "form-control" } })  } 

然后,在我的控制器方法中,我想做类似以下的事情:

 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); } 

直接的问题似乎是我的视图中的DropDownListForEditorFor方法都在抱怨,这是有道理的,因为我已经在我的视图模型中指定了StationTimetablesIEnumerable ,并且我无法访问StationIdArrivalDeparture属性IEnumerable 。 这些属性是IEnumerable持有的实体的一部分。

不幸的是,我不知道如何使用Html帮助器来创建一个表单,我可以使用许多StationTimetable实体填充StationTimetables 。 如果我可以在我的Create方法中获得多个StationTimetable条目,那么我认为在此之后将它们添加到数据库中会有问题。

感谢您的任何帮助。

您需要使您的StationTimetables属性IList并使用索引器,以便正确命名属性并可以在回发后绑定

 @for (var i = 0; i < 10; i++) {  @Html.DropDownListFor(m => m.StationTimetables[i].StationId, Model.StationList, "---", htmlAttributes: new { @class = "form-control col-md-2" }) @Html.EditorFor(m => m.StationTimetables[i].Arrival, new { htmlAttributes = new { @class = "form-control" } }) @Html.EditorFor(m => m.StationTimetables[i].Departure, new { htmlAttributes = new { @class = "form-control" } })  } 

例如,这将生成正确的名称属性

   

如果您无法从IEnumerable更改它,则可以为typeof StationTimetable创建自定义EditorTemplate

查看/共享/ EditorTemplates / StationTimetable.cshtml

 @model YourAssembly.StationTimetable  @Html.DropDownListFor(m => m.StationId, (SelectList)ViewData["StationList"], "---", new { @class = "form-control col-md-2" }) @Html.EditorFor(m => m.Arrival, new { htmlAttributes = new { @class = "form-control" } }) @Html.EditorFor(m => m.Departure, new { htmlAttributes = new { @class = "form-control" } })  

然后在主视图中

 @EditorFor(m => m.StationTimetables, new { StationList = Model.Model.StationList }) 

此方法意味着在将模型传递给视图之前,需要在控制器中初始化包含10个项目的StationTimetables属性。

在任何情况下,我推荐使用EditorFor()方法,因为在for循环中使用DropDownListFor()出现了一个bug(已报告但尚未解决)。

但是我怀疑你并没有真正总是有10个站时间表( 我让用户插入最多 10个 )这使得这种方法不灵活 – 例如,如果你向属性添加validation属性,模型将无效,除非所有填写了10个时间表属性。最好使用javascript或BeginCollectionItem帮助程序动态添加新的时间表。 这个答案中包含了这两种方法的一个例子