Создадим в базе 3 таблички – Students, Courses и коммутационную CourseStudent
Courses
CourseStudent
В студии создадим их классы
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
using System; using System.Collections.Generic; using System.Linq; using System.Web; namespace modelsTraining2.Models { public class Student { public int Id { get; set; } public string Name { get; set; } public string Surname { get; set; } public virtual ICollection<Course> Courses { get; set; } public Student() { Courses = new List<Course>(); } } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
using System; using System.Collections.Generic; using System.Linq; using System.Web; namespace modelsTraining2.Models { public class Course { public int Id { get; set; } public string Name { get; set; } public virtual ICollection<Student> Students { get; set; } public Course() { Students = new List<Student>(); } } } |
И контекст, в который добавим коммутационную табличку
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
using System; using System.Collections.Generic; using System.Data.Entity; using System.Linq; using System.Web; namespace modelsTraining2.Models { public class StudentsContext:DbContext { public DbSet<Student> Students { get; set; } public DbSet<Course> Courses { get; set; } public StudentsContext() : base("DbConnection"){ } protected override void OnModelCreating(DbModelBuilder modelBuilder) { modelBuilder.Entity<Course>().HasMany(c => c.Students) .WithMany(s => s.Courses) .Map(t => t.MapLeftKey("CourseId") .MapRightKey("StudentId") .ToTable("CourseStudent")); } } } |
Далее, создадим контроллер и представления по шаблону CRUD
Правой кнопкой на контроллере -> Add
Вот какой код получится у нас для контроллера
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 |
using System; using System.Collections.Generic; using System.Data; using System.Data.Entity; using System.Linq; using System.Threading.Tasks; using System.Net; using System.Web; using System.Web.Mvc; using modelsTraining2.Models; namespace modelsTraining2.Controllers { public class StudentsController : Controller { private StudentsContext db = new StudentsContext(); // GET: Students public async Task<ActionResult> Index() { return View(await db.Students.ToListAsync()); } // GET: Students/Details/5 public async Task<ActionResult> Details(int? id) { if (id == null) { return new HttpStatusCodeResult(HttpStatusCode.BadRequest); } Student student = await db.Students.FindAsync(id); if (student == null) { return HttpNotFound(); } return View(student); } // GET: Students/Create public ActionResult Create() { return View(); } // POST: Students/Create // To protect from overposting attacks, please enable the specific properties you want to bind to, for // more details see https://go.microsoft.com/fwlink/?LinkId=317598. [HttpPost] [ValidateAntiForgeryToken] public async Task<ActionResult> Create([Bind(Include = "Id,Name,Surname")] Student student) { if (ModelState.IsValid) { db.Students.Add(student); await db.SaveChangesAsync(); return RedirectToAction("Index"); } return View(student); } // GET: Students/Edit/5 public async Task<ActionResult> Edit(int? id) { if (id == null) { return new HttpStatusCodeResult(HttpStatusCode.BadRequest); } Student student = await db.Students.FindAsync(id); if (student == null) { return HttpNotFound(); } return View(student); } // POST: Students/Edit/5 // To protect from overposting attacks, please enable the specific properties you want to bind to, for // more details see https://go.microsoft.com/fwlink/?LinkId=317598. [HttpPost] [ValidateAntiForgeryToken] public async Task<ActionResult> Edit([Bind(Include = "Id,Name,Surname")] Student student) { if (ModelState.IsValid) { db.Entry(student).State = EntityState.Modified; await db.SaveChangesAsync(); return RedirectToAction("Index"); } return View(student); } // GET: Students/Delete/5 public async Task<ActionResult> Delete(int? id) { if (id == null) { return new HttpStatusCodeResult(HttpStatusCode.BadRequest); } Student student = await db.Students.FindAsync(id); if (student == null) { return HttpNotFound(); } return View(student); } // POST: Students/Delete/5 [HttpPost, ActionName("Delete")] [ValidateAntiForgeryToken] public async Task<ActionResult> DeleteConfirmed(int id) { Student student = await db.Students.FindAsync(id); db.Students.Remove(student); await db.SaveChangesAsync(); return RedirectToAction("Index"); } protected override void Dispose(bool disposing) { if (disposing) { db.Dispose(); } base.Dispose(disposing); } } } |
А вот вьюшечку для Details поправим таким образом
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
@model modelsTraining2.Models.Student @{ ViewBag.Title = "Details"; } <h2>Details</h2> <div> <h4>Student</h4> <hr /> <dl class="dl-horizontal"> <dt> @Html.DisplayNameFor(model => model.Name) </dt> <dd> @Html.DisplayFor(model => model.Name) </dd> <dt> @Html.DisplayNameFor(model => model.Surname) </dt> <dd> @Html.DisplayFor(model => model.Surname) </dd> <dt>Courses</dt> <dd> @foreach (var c in Model.Courses) { <p>@c.Name </p> } </dd> </dl> </div> <p> @Html.ActionLink("Edit", "Edit", new { id = Model.Id }) | @Html.ActionLink("Back to List", "Index") </p> |
Добавим туда перечисления, курсы…
1 2 3 4 5 6 7 8 9 10 |
<dt>Courses</dt> <dd> @foreach (var c in Model.Courses) { <p>@c.Name </p> } </dd> |
Курсы у нас отобразились. Что будем делать дальше?
Изменение метода Edit
Напишем метод Edit2
Метод после шаблонов CRUD дает возможность изменить только имя и фамилию, поэтому нам нужно изменить контроллер и представление таким образом, чтобы мы могли поменять курсы, сделаем это следующим образом
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
public ActionResult Edit2(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 Edit2(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"); } |