ACTUALIZACIÓN a la respuesta de Leniency:
También podemos crear dos relaciones uno a muchos con el primer enfoque del modelo. De cualquier manera, no podemos tener el enlace del modelo como ocurre en la relación pura de M2M (sin tablas de carga útil o tablas de combinación pura - PJT).
Además, en el controlador (andamio), podemos utilizar un modelo de vista para las operaciones CRUD según el requisito. Supuestamente, tenemos una FloorViewModel con la siguiente definición:
public class FloorViewModel
{
private Model2Container context = new Model2Container();
[Display(Name = "Student List")]
[Required(ErrorMessage = "Please select atleast one student from the list.")]
public int[] MyStudents { get; set; }
public Floor MyFloor { get; set; }
public MultiSelectList StudentsList { get; set; }
public StudentFloorJoin Join { get; set; }
}
La acción de crear en el controlador sería:
//
// GET: /Floor/Create
public ActionResult Create()
{
var model = new FloorViewModel() { StudentsList = new MultiSelectList(context.Students, "Id", "Name") };
return View(model);
}
//
// POST: /Floor/Create
[HttpPost]
public ActionResult Create(FloorViewModel floor)
{
if (ModelState.IsValid)
{
context.Floors.Add(floor.MyFloor);
context.SaveChanges();
}
foreach (var student in floor.MyStudents)
{
context.StudentFloorJoins.Add(new StudentFloorJoin() { Student = context.Students.Find(student), Floor = floor.MyFloor, Room = floor.Join.Room });
}
if (ModelState.IsValid)
{
context.SaveChanges();
return RedirectToAction("Index");
}
context.Floors.Remove(floor.MyFloor);
floor.StudentsList = new MultiSelectList(context.Students, "Id", "Name", floor.MyStudents);
return View(floor);
}
y la acción Editar sería algo así como:
//
// GET: /Floor/Edit
public ActionResult Edit(int id)
{
Floor floor = context.Floors.Single(x => x.Id == id);
int[] ids = (from i in floor.StudentFloorJoins select i.Student.Id).ToArray();
var model = new FloorViewModel() { StudentsList = new MultiSelectList(context.Students, "Id", "Name", ids), MyFloor = floor, Join = new StudentFloorJoin() { Room = floor.StudentFloorJoins.Count == 0 ? "" : floor.StudentFloorJoins.First().Room } };
return View(model);
}
//
// POST: /Floor/Edit
[HttpPost]
public ActionResult Edit(FloorViewModel floor)
{
if (ModelState.IsValid)
{
var item = floor.MyFloor;
var itemEntry1 = context.Entry<Floor>(item);
itemEntry1.State = EntityState.Modified;
var query = (from i in context.StudentFloorJoins where i.Floor.Id == item.Id select i.Id);
foreach (var studentfloor in query)
{
context.StudentFloorJoins.Remove(context.StudentFloorJoins.Find(studentfloor));
}
context.SaveChanges();
foreach (var student in floor.MyStudents)
{
context.StudentFloorJoins.Add(new StudentFloorJoin() { Student = context.Students.Find(student), Floor = floor.MyFloor, Room = floor.Join.Room });
}
context.SaveChanges();
return RedirectToAction("Index");
}
floor.StudentsList = new MultiSelectList(context.Students, "Id", "Name", floor.MyStudents);
return View(floor);
}
En Ver, podemos enviar el objeto de FloorModelView como:
@model ManyToManyAutoGen.Models.FloorViewModel
@{
ViewBag.Title = "Create";
}
<h2>Create</h2>
<script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
@using (Html.BeginForm()) {
@Html.ValidationSummary(true)
<fieldset>
<legend>Floor</legend>
@Html.Partial("_CreateOrEdit", Model)
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
}
<div>
@Html.ActionLink("Back to List", "Index")
</div>
y, finalmente, _CreateOrEdit miradas parciales como:
@model ManyToManyAutoGen.Models.FloorViewModel
@* This partial view defines form fields that will appear when creating and editing entities *@
<div class="editor-label">
@Html.LabelFor(model => model.MyFloor.FloorName)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.MyFloor.FloorName)
@Html.ValidationMessageFor(model => model.MyFloor.FloorName)
</div>
<div class="editor-label">
@Html.LabelFor(model => model.MyStudents)
</div>
<div class="editor-field">
@Html.ListBoxFor(model => model.MyStudents, Model.StudentsList)
@Html.ValidationMessageFor(model => model.MyStudents)
</div>
<div class="editor-label">
@Html.LabelFor(model => model.Join.First().Room)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.Join.First().Room)
@Html.ValidationMessageFor(model => model.Join)
</div>
Gracias por su entrada. Por favor revisa la sección de actualización y avísame si el código en el controlador puede hacerse más delgado y elegante. –
Estoy buscando la sección de actualización con un controlador que mencionas ... ¿no lo encuentras? – Leniency
Eso es malo. Parece que ha sido rechazado por otros usuarios, aunque es solo una continuación de su respuesta. Déjame ponerlo en una respuesta separada. –