Работа с моделями со связью многие-ко-многим

Данное руководство устарело. Актуальное руководство: Руководство по ASP.NET Core

Последнее обновление: 31.10.2015

Простой вывод связанных данных со связью "многие-ко-многим" не представляет особого труда. Однако не совсем понятно, как делать создание и редактирование подобных моделей. Продолжим начатый в прошлой теме пример со студентами и курсами и внесем в него функциональность редактирования студентов.

В итоге форма редактирования у нас будет выглядеть примерно так:

Итак, добавим в контроллер HomeController следующее действие Edit:

public ActionResult Edit(int id = 0)
{
    Student student = db.Students.Find(id);
    if (student == null)
    {
        return HttpNotFound();
    }
    ViewBag.Courses = db.Courses.ToList();
    return View(student);
}

[HttpPost]
public ActionResult Edit(Student student, int[] selectedCourses)
{
    Student newStudent = db.Students.Find(student.Id);
    newStudent.Name = student.Name;
    newStudent.Surname = student.Surname;
                
    newStudent.Courses.Clear();
    if (selectedCourses != null)
    {
        //получаем выбранные курсы
        foreach (var c in db.Courses.Where(co => selectedCourses.Contains(co.Id)))
        {
            newStudent.Courses.Add(c);
        }
    }

	db.Entry(newStudent).State = EntityState.Modified;
    db.SaveChanges();
    return RedirectToAction("Index");
}

Действие Edit представляет два метода - для запроса get и для запроса post. Метод, обрабатывающий запрос get, стандартный - он передает в представление редактируемую модель, а также список всех курсов через ViewBag.Courses = db.Courses.ToList();, чтобы мы могли затем эти курсы вывести в представлении.

Метод post принимает полученные данные, только кроме модели Student сюда также передаются все выбранные курсы в виде массива id курсов. В этот массив и будут помещаться все значения всех отмеченных на форме флажков. В самом методе после прохождения валидации мы устанавливаем новые значения свойств модели.

Затем нам надо установить в коллекции Courses у студента все отмеченные курсы. Для этого проходим по всем курсам из базы данных, и если они были отмечены на форме и отсутствуют в списке, то добавляем их. Неотмеченные удаляем (если они есть в списке). В итоге информация в базе данных будет соотвествующим образом обновлена.

И напоследок добавим само представление Edit.cshtml:

@using TeamMvc4.Models
@model Student
@{
    ViewBag.Title = "Edit";
}


@using (Html.BeginForm()) {

    <fieldset>
        <legend>Студент</legend>

        @Html.HiddenFor(model => model.Id)

        <div class="editor-label"><b>Имя</b></div>
        <div class="editor-field">
            @Html.EditorFor(model => model.Name)
        </div>

        <div class="editor-label"><b>Фамилия</b></div>
        <div class="editor-field">
            @Html.EditorFor(model => model.Surname)
        </div>
        <div class="editor-label"><b>Курсы</b></div>
        @foreach (Course c in ViewBag.Courses)
		{
			<input type="checkbox" name="selectedCourses" value="@c.Id"
               @(Model.Courses.Contains(c) ? "checked=\"checked\"" : "") />@c.Name <br />
        }

        <p>
            <input type="submit" value="Сохранить" />
        </p>
    </fieldset>
}

Ну а сохранение модели будет во многом идентично редактированию.

Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850