Hej, nie umiem do końca skumać ja się binduje przy wielokrotnym wyborze w MVC6 lub Core2. Przykład zaczerpnięty z samouczka .net:
Posiadam model:
public class Course
{
[DatabaseGenerated(DatabaseGeneratedOption.None)]
[Display(Name = "Number")]
public int CourseID { get; set; }
[StringLength(50, MinimumLength = 3)]
public string Title { get; set; }
[Range(0, 5)]
public int Credits { get; set; }
public int DepartmentID { get; set; }
public Department Department { get; set; }
public ICollection<Enrollment> Enrollments { get; set; }
public ICollection<CourseAssignment> CourseAssignments { get; set; }
}
Kontroler dla edycji rekordu:
(...)
[HttpPost, ActionName("Edit")]
[ValidateAntiForgeryToken]
public async Task<IActionResult> EditPost(int? id)
{
if (id == null)
{
return NotFound();
}
var courseToUpdate = await _context.Courses
.SingleOrDefaultAsync(c => c.CourseID == id);
if (await TryUpdateModelAsync<Course>(courseToUpdate,
"",
c => c.Credits, c => c.DepartmentID, c => c.Title))
{
try
{
await _context.SaveChangesAsync();
}
catch (DbUpdateException /* ex */)
{
//Log the error (uncomment ex variable name and write a log.)
ModelState.AddModelError("", "Unable to save changes. " +
"Try again, and if the problem persists, " +
"see your system administrator.");
}
return RedirectToAction(nameof(Index));
}
PopulateDepartmentsDropDownList(courseToUpdate.DepartmentID);
return View(courseToUpdate);
}
(...)
Zapełnianie listy dropdown w kontrolerze:
(...)
private void PopulateDepartmentsDropDownList(object selectedDepartment = null)
{
var departmentsQuery = from d in _context.Departments
orderby d.Name
select d;
ViewBag.DepartmentID = new SelectList(departmentsQuery.AsNoTracking(), "DepartmentID", "Name", selectedDepartment);
}
(...)
Oraz widok:
@model ContosoUniversity.Models.Course
(...)
<div class="form-group">
<label asp-for="Department" class="control-label"></label>
<select asp-for="DepartmentID" class="form-control" asp-items="ViewBag.DepartmentID">
<option value="">-- Select Department --</option>
</select>
<span asp-validation-for="DepartmentID" class="text-danger" />
</div>
(...)
I tu jest wszystko jasne dla mnie. W kontrolerze jest tworzona dynamiczna lista ViewBag
, pobiera ona z kontekstu nazwy działów. Widok edycji pozwala wybrać jeden z działów poprzez <select>
. Kontroler w akcji Edit
, po wypełnieniu formularza nadpisuje dane. I to wszystko jest zrozumiałe.
Do końca nie wiem jak powinna wyglądać architektura, jeśli chcę dokonać wielokrotnego wyboru. DepartmentID
, jako model w bazie EF nie może być tablicą. W takim razie powinien powstać ViewModel, np. typu IEnumerable<??> Departments {get;set;}
, który zastąpi:
asp-for="DepartmentID"
na
asp-for="Departments"
Czy w takim wypadku ViewModel
musi zawierać wszystkie pozostałe własności modelu? Bo rozumiem, że w widoku będziemy musieli wtedy wywołać @model ViewModel
zamiast @model Model
Jeśli tak, to dalej nie wiem jak bindować wielokrotny wybór z bazą, by zapisać w niej wybór dla kilku DepartmentID. Na SO nie udało mi się znaleźć przykładu który by wyjaśnił mi zagadnienie bindowania VM z bazą/modelem.