Reputation:
I created two models of Class and Teacher, I want to configure many to many relationship using code first approach with two models. When I add information into class and teacher tables, value not insert into TeacherClasses Table using many to many relationship Entity Framework code first approach.
Here code of models and controller below.
This is Class Model
public class Class
{
[Key]
public int ClassId { get; set; }
[Required]
public string ClassName { get; set; }
public virtual ICollection<Teacher> Teachers { get; set; }
}
This is Teacher Model
public class Teacher
{
[Key]
public int TeacherId { get; set; }
[Required]
public string TeacherName { get; set; }
[DataType(DataType.Date)]
public DateTime JoiningDate { get; set; }
public decimal Salary { get; set; }
public string Email { get; set; }
public virtual ICollection<Class> Classes { get; set; }
[NotMapped]
public virtual Class Class { get; set; }
[NotMapped]
public virtual ICollection<int> SelectedClassList { get; set; }
}
This is Teacher Controller
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include = "TeacherId,TeacherName,JoiningDate,Salary,Email,Classes,Class,SelectedClassList")] Teacher teacher)
{
if (ModelState.IsValid)
{
db.Teachers.Add(teacher);
db.SaveChanges();
teacher.Classes = new Collection<Class>();
foreach (var classId in teacher.SelectedClassList)
{
teacher.Classes.Add(new Class {ClassId = classId });
}
return RedirectToAction("Index");
}
return View(teacher);
}
this is image of database tables in database class, teacher and teacherclasses tables shown
This is View of Teacher
<div class="form-group">
@Html.Label("Class List", htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@*@Html.ListBox("SelectedClassList", ViewData["ClassList"] as MultiSelectList)
@Html.ValidationMessageFor(model => model.Classes, "", new { @class = "text-danger" })*@
@Html.ListBoxFor(model => model.SelectedClassList, new MultiSelectList(ViewBag.ClassList, "value", "text"), new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.SelectedClassList, "", new { @class = "text-danger" })
</div>
</div>
Upvotes: 0
Views: 199
Reputation: 109117
From your description and the way you're saving the data there seem to be two possible scenarios you're trying to achieve:
Whichever it is, the rule is always:
So for the first scenario that would be:
foreach (var classId in teacher.SelectedClassList)
{
var class = new Class { ClassId = classId }; // "stub" entity
db.Classes.Attach(class);
teacher.Classes.Add(class); // Assuming that teacher.Classes isn't null
}
db.Teachers.Add(teacher); // <= Add
db.SaveChanges();
And the second scenario:
db.Teachers.Attach(teacher); // <= Attach
foreach (var classId in teacher.SelectedClassList)
{
var class = new Class { ClassId = classId }; // "stub" entity
db.Classes.Attach(class);
teacher.Classes.Add(class); // Assuming that teacher.Classes isn't null
}
db.SaveChanges();
As you see, you never need to pull existing entities from the database. For creating associations all EF needs tho know is the ID values of the entities at both ends, so working with stub entities is the ideal approach here.
In the first scenario, if you don't attach the classes before adding the teacher, the classes will be marked as Added
too, and you'll insert empty class records into the database (if they pass validation at all).
Upvotes: 1