I have two models set up as follows:
public class NewCourseCategoryForm
{
public int NewCourseCategoryFormID { get; set; }
public virtual ICollection<ProposedCourse> ProposedCourse { get; set; }
}
And then:
public class ProposedCourse
{
public int ProposedCourseID { get; set; }
public string ProposedCourseName { get; set; }
public string ProposedCourseDescription { get; set; }
public NewCourseCategoryForm { get; set; }
}
In my DbContext class definition, I have the following code which defines the relationships between the two aforementioned tables:
modelBuilder.Entity<NewCourseCategoryForm>(entity =>
{
entity.HasKey(e => NewCourseCategoryFormID
entity.Property(e => e.NewCourseCategoryFormID).HasColumnName("NewCourseCategoryFormID");
entity.HasMany(d => d.ProposedCourse)
.WithOne(p => p.NewCourseCategoryForm);
modelBuilder.Entity<ProposedCourse>(entity =>
{
entity.HasKey(e => e.ProposedCourseID);
entity.Property(e => e.ProposedCourseName).HasColumnName("ProposedCourseName");
entity.Property(e => e.ProposedCourseDescription).HasColumnName("ProposedCourseDescription");
});
I want to create the CRUD pages for the NewCourseCategoryForm
page. On the "Create" page, instead of seeing ProposedCourseID
, I want to see the textboxes related to the ProposedCourse
model for ProposedCourseName
and ProposedCourseDescription
. Whenever the user creates a new NewCourseCategoryForm
, I want for records to be entered on to both tables like this:
+----------------------------+------------------+
| NewCourseCategoryFormID | ProposedCourseID |
+----------------------------+------------------+
| 1 | 123 |
+----------------------------+------------------+
+------------------+--------------------+---------------------------+
| ProposedCourseID | ProposedCourseName | ProposedCourseDescription |
+------------------+--------------------+---------------------------+
| 123 | Algebra 101 | Beginner algebra |
+------------------+--------------------+---------------------------+
I'm feel certain that Entity Framework can handle something like this, but I have no idea where to begin looking. How can I make this happen? I even need the user to be able to enter a dynamic number of "Proposed Courses". So how can I accomplish that?
This should do the trick:
CourseViewModels.cs:
using System.Collections.Generic;
namespace Test.Models
{
public class NewCourseCategoryForm
{
public int NewCourseCategoryFormID { get; set; }
public virtual ICollection<ProposedCourse> ProposedCourses { get; set; }
}
public class ProposedCourse
{
public int ProposedCourseID { get; set; }
public string ProposedCourseName { get; set; }
public string ProposedCourseDescription { get; set; }
public NewCourseCategoryForm Form { get; set; }
}
}
CoursesController.cs:
using System.Linq;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using Test.Models;
namespace Test.Controllers
{
public class CoursesController : Controller
{
private readonly ILogger<CoursesController> _logger;
public CoursesController(ILogger<CoursesController> logger)
{
_logger = logger;
}
[HttpGet]
public IActionResult Create()
{
return View();
}
[HttpPost]
public IActionResult Create(NewCourseCategoryForm form)
{
var newForm = new NewCourseCategoryForm
{
ProposedCourses = form.ProposedCourses.Select(s => new ProposedCourse
{
ProposedCourseName = s.ProposedCourseName,
ProposedCourseDescription = s.ProposedCourseDescription
}).ToList()
};
// _context.NewCourseCategoryForms.Add(newForm);
// _context.SaveChanges();
return RedirectToAction("Create");
}
}
}
Create.cshtml:
@model NewCourseCategoryForm
@{
ViewData["Title"] = "Home Page";
}
<form method="post">
<div id="courses" class="row">
<div class="col-md-6">
<div class="form-group">
<label>Course name</label>
<input type="text" class="form-control" name="ProposedCourses[0].ProposedCourseName" placeholder="Name...">
</div>
</div>
<div class="col-md-6">
<div class="form-group">
<label>Course description</label>
<input type="text" class="form-control" name="ProposedCourses[0].ProposedCourseDescription" placeholder="Description...">
</div>
</div>
</div>
<button class="btn btn-primary" type="button" onclick="create()">New...</button>
<button class="btn btn-secondary" type="submit">Create</button>
</form>
@section Scripts
{
<script type="text/javascript">
var counter = 1;
const create = () => {
$("#courses").append(`
<div class="col-md-6">
<div class="form-group">
<label>Course name</label>
<input type="text" class="form-control" name="ProposedCourses[` + counter + `].ProposedCourseName" placeholder="Name...">
</div>
</div>
<div class="col-md-6">
<div class="form-group">
<label>Course description</label>
<input type="text" class="form-control" name="ProposedCourses[` + counter + `].ProposedCourseDescription" placeholder="Description...">
</div>
</div>
`);
counter++;
}
</script>
}