Created
November 4, 2021 16:42
-
-
Save bpesquet/246828ea0eb4a8e8de218fb7675c56fe to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Threading.Tasks; | |
using Microsoft.AspNetCore.Mvc; | |
using Microsoft.EntityFrameworkCore; | |
using MvcUniversity.Data; | |
using MvcUniversity.Models; | |
namespace MvcUniversity.Controllers | |
{ | |
public class InstructorsController : Controller | |
{ | |
private readonly MvcUniversityContext _context; | |
public InstructorsController(MvcUniversityContext context) | |
{ | |
_context = context; | |
} | |
// GET: Instructors | |
public async Task<IActionResult> Index() | |
{ | |
var instructors = await _context.Instructors | |
.Include(i => i.Courses) | |
.AsNoTracking() | |
.ToListAsync(); | |
return View(instructors); | |
} | |
// GET: Instructors/Details/5 | |
public async Task<IActionResult> Details(int? id) | |
{ | |
if (id == null) | |
{ | |
return NotFound(); | |
} | |
var instructor = await _context.Instructors | |
.Include(i => i.Courses) | |
.AsNoTracking() | |
.FirstOrDefaultAsync(m => m.Id == id); | |
if (instructor == null) | |
{ | |
return NotFound(); | |
} | |
return View(instructor); | |
} | |
// GET: Instructors/Create | |
public IActionResult Create() | |
{ | |
return View(); | |
} | |
// POST: Instructors/Create | |
// To protect from overposting attacks, enable the specific properties you want to bind to. | |
// For more details, see http://go.microsoft.com/fwlink/?LinkId=317598. | |
[HttpPost] | |
[ValidateAntiForgeryToken] | |
public async Task<IActionResult> Create([Bind("Id,LastName,FirstName,HireDate")] Instructor instructor) | |
{ | |
if (ModelState.IsValid) | |
{ | |
_context.Add(instructor); | |
await _context.SaveChangesAsync(); | |
return RedirectToAction(nameof(Index)); | |
} | |
return View(instructor); | |
} | |
// GET: Instructors/Edit/5 | |
public async Task<IActionResult> Edit(int? id) | |
{ | |
if (id == null) | |
{ | |
return NotFound(); | |
} | |
var instructor = await _context.Instructors | |
.Include(i => i.Courses) | |
.AsNoTracking() | |
.FirstOrDefaultAsync(m => m.Id == id); | |
if (instructor == null) | |
{ | |
return NotFound(); | |
} | |
PopulateAssignedCourseViewModel(instructor); | |
return View(instructor); | |
} | |
// POST: Instructors/Edit/5 | |
// To protect from overposting attacks, enable the specific properties you want to bind to. | |
// For more details, see http://go.microsoft.com/fwlink/?LinkId=317598. | |
[HttpPost] | |
[ValidateAntiForgeryToken] | |
public async Task<IActionResult> Edit(int id, [Bind("Id,LastName,FirstName,HireDate")] Instructor instructor, string[] selectedCourses) | |
{ | |
if (id != instructor.Id) | |
{ | |
return NotFound(); | |
} | |
if (ModelState.IsValid) | |
{ | |
try | |
{ | |
_context.Update(instructor); | |
UpdateInstructorCourses(selectedCourses, instructor.Id); | |
await _context.SaveChangesAsync(); | |
} | |
catch (DbUpdateConcurrencyException) | |
{ | |
if (!InstructorExists(instructor.Id)) | |
{ | |
return NotFound(); | |
} | |
else | |
{ | |
throw; | |
} | |
} | |
return RedirectToAction(nameof(Index)); | |
} | |
return View(instructor); | |
} | |
// GET: Instructors/Delete/5 | |
public async Task<IActionResult> Delete(int? id) | |
{ | |
if (id == null) | |
{ | |
return NotFound(); | |
} | |
var instructor = await _context.Instructors | |
.FirstOrDefaultAsync(m => m.Id == id); | |
if (instructor == null) | |
{ | |
return NotFound(); | |
} | |
return View(instructor); | |
} | |
// POST: Instructors/Delete/5 | |
[HttpPost, ActionName("Delete")] | |
[ValidateAntiForgeryToken] | |
public async Task<IActionResult> DeleteConfirmed(int id) | |
{ | |
var instructor = await _context.Instructors.FindAsync(id); | |
_context.Instructors.Remove(instructor); | |
await _context.SaveChangesAsync(); | |
return RedirectToAction(nameof(Index)); | |
} | |
private bool InstructorExists(int id) | |
{ | |
return _context.Instructors.Any(e => e.Id == id); | |
} | |
// Add courses info to view data | |
private void PopulateAssignedCourseViewModel(Instructor instructor) | |
{ | |
var allCourses = _context.Courses; | |
var instructorCourses = new HashSet<int>( | |
instructor.Courses.Select(c => c.Id)); | |
var viewModel = new List<AssignedCourseViewModel>(); | |
foreach (var course in allCourses) | |
{ | |
viewModel.Add(new AssignedCourseViewModel | |
{ | |
Id = course.Id, | |
Title = course.Title, | |
Assigned = instructorCourses.Contains(course.Id) | |
}); | |
} | |
ViewData["Courses"] = viewModel; | |
} | |
// Update instructor courses according to selections in Edit view | |
public async void UpdateInstructorCourses(string[] selectedCourses, int instructorId) | |
{ | |
// Load instructor to update from DB | |
var instructor = await _context.Instructors | |
.Include(i => i.Courses) | |
.FirstOrDefaultAsync(m => m.Id == instructorId); | |
if (selectedCourses == null) | |
{ | |
instructor.Courses = new List<Course>(); | |
return; | |
} | |
var selectedCoursesHS = new HashSet<string>(selectedCourses); | |
var instructorCourses = new HashSet<int> | |
(instructor.Courses.Select(c => c.Id)); | |
foreach (var course in _context.Courses) | |
{ | |
if (selectedCoursesHS.Contains(course.Id.ToString())) | |
{ | |
// Course has been selected in the UI | |
if (!instructorCourses.Contains(course.Id)) | |
{ | |
// Add relationship between instructor and course | |
instructor.Courses.Add(course); | |
} | |
} | |
else | |
{ | |
// Course has not been selected in the UI | |
if (instructorCourses.Contains(course.Id)) | |
{ | |
// Remove existing relationship between instructor and course | |
var courseToRemove = instructor.Courses.Single( | |
c => c.Id == course.Id); | |
instructor.Courses.Remove(courseToRemove); | |
} | |
} | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment