在数据库设计中,多对多关系是一个常见的概念,它描述了两个实体之间复杂的关联关系。例如,一个训练师可以训练多个课程,而一个课程也可以由多个训练师来管理。为了在数据库中实现这种关系,需要创建一个额外的关联表来存储这些关系。
在本文中,将通过一个实际的示例来展示如何在Entity Framework中实现多对多关系。将创建一个名为“TrainsOnCourse”的新表,用于存储训练师和课程之间的关联关系。
首先,需要创建一个名为“Trainer”的模型。这个模型将代表数据库中的训练师实体。可以使用Entity Framework的迁移功能来更新数据库,以便在SQL Server数据库中添加训练师表。
public class Trainer
{
public int TrainerId { get; set; }
public string Name { get; set; }
// 导航属性
public virtual ICollection<TrainsOnCourse> TrainsOnCourses { get; set; }
}
接下来,需要在DbContext类中添加一个DBSet实体属性,用于表示TrainsOnCourse表。
public class DNSCContext : DbContext
{
public DbSet<Trainer> Trainers { get; set; }
public DbSet<TrainsOnCourse> TrainsOnCourses { get; set; }
}
然后,需要修改Trainer模型,添加导航属性,并保存在列表框中选择的集合项。
public class Trainer
{
public int TrainerId { get; set; }
public string Name { get; set; }
// 导航属性
public virtual ICollection<TrainsOnCourse> TrainsOnCourses { get; set; }
}
完成模型的修改后,需要再次构建解决方案,并执行“Add-Migration”命令,以便在数据库中添加TrainsOnCourse表。
Add-Migration AddTrainsOnCourseTable
更新数据库,运行迁移文件。
update-database
此时,打开SQL Server,应该可以看到TrainsOnCourse表已经被创建,并且包含两个外键。
接下来,需要添加一个新的控制器“Trainer”。在控制器中,需要选择Trainer.cs模型和DNSCContext。
然后,需要修改Create Action方法,以便从数据库中填充课程表的多选列表值。
public ActionResult Create()
{
ViewBag.CourseId = new SelectList(db.Courses, "CourseId", "Title");
return View();
}
在Trainer文件夹中的Create.cshtml视图页面中,需要添加一个ListBoxControl。
<select id="CourseId" name="CourseId" multiple="multiple">
<option value="1">课程1</option>
<option value="2">课程2</option>
<option value="3">课程3</option>
</select>
运行应用程序,并导航到“Trainer/Create”Action方法,通过在URL中输入相应的路径。应该能够看到一个包含一组值的ListBox。
接下来,需要修改HTTPPost Create Action方法,以便保存选定的项到数据库。
[HttpPost]
public ActionResult Create(Trainer trainer, List<int> CourseIds)
{
if (ModelState.IsValid)
{
db.Trainers.Add(trainer);
db.SaveChanges();
foreach (var courseId in CourseIds)
{
var trainsOnCourse = new TrainsOnCourse
{
TrainerId = trainer.TrainerId,
CourseId = courseId
};
db.TrainsOnCourses.Add(trainsOnCourse);
}
db.SaveChanges();
return RedirectToAction("Index");
}
return View(trainer);
}
然后,需要修改Trainer控制器中的Edit Action方法,以便处理ListBox控件。
在Trainer文件夹中的Edit.cshtml视图页面中,需要添加一个ListBoxControl。
<select id="CourseId" name="CourseId" multiple="multiple">
<option value="1">课程1</option>
<option value="2">课程2</option>
<option value="3">课程3</option>
</select>
打开HTTPPost Edit Action方法的Trainer控制器,并执行所需的操作。
[HttpPost]
public ActionResult Edit(int id, List<int> CourseIds)
{
var trainer = db.Trainers.Find(id);
if (trainer == null)
{
return HttpNotFound();
}
trainer.Name = Request.Form["Name"];
db.Entry(trainer).State = EntityState.Modified;
var existingCourses = db.TrainsOnCourses.Where(toc => toc.TrainerId == id).ToList();
foreach (var course in existingCourses)
{
if (!CourseIds.Contains(course.CourseId))
{
db.TrainsOnCourses.Remove(course);
}
}
foreach (var courseId in CourseIds)
{
var trainsOnCourse = existingCourses.FirstOrDefault(toc => toc.CourseId == courseId);
if (trainsOnCourse == null)
{
trainsOnCourse = new TrainsOnCourse
{
TrainerId = id,
CourseId = courseId
};
db.TrainsOnCourses.Add(trainsOnCourse);
}
}
db.SaveChanges();
return RedirectToAction("Index");
}