C# MVC EF数据库先多对多
有人能先弄清楚EF数据库中的多对多关系是如何工作的吗。 例如,C# MVC EF数据库先多对多,c#,asp.net-mvc,entity-framework,C#,Asp.net Mvc,Entity Framework,有人能先弄清楚EF数据库中的多对多关系是如何工作的吗。 例如,Student和Course表,其中关系为多对多。我已经有一个数据库了 因此,我创建了一个.edmx 学生和课程的类是自动创建的。我在StudentCourseViewModel.cs中添加了一个新类。我们的想法是控制与它的关系。 我的StudentCourseViewModel包含以下内容: public class StudentCourseViewModel { public Student Student{ get;
Student
和Course
表,其中关系为多对多。我已经有一个数据库了
因此,我创建了一个.edmx
学生
和课程
的类是自动创建的。我在StudentCourseViewModel.cs
中添加了一个新类。我们的想法是控制与它的关系。
我的StudentCourseViewModel
包含以下内容:
public class StudentCourseViewModel
{
public Student Student{ get; set; }
public IEnumerable<SelectListItem> AllCourses{ get; set; }
private List<int> _selectedCourse;
public List<int> SelectedCourse
{
get
{
if (_selectedCourse == null)
{
_selectedCourse = Student.Courses.Select(m => m.pkID).ToList();
}
return _selectedCourse;
}
set { _selectedCourse = value; }
}
public ActionResult Create()
{
ViewBag.Courses = new SelectList(db.Courses, "pkID", "Name");
return View();
}
public ActionResult Create(StudentCourseViewModel model,[Bind(Include = "pkID,Name")] Student student)
{
if (ModelState.IsValid)
{
if (student == null)
return HttpNotFound();
// Remove items that were unselected
db.Courses.Where(m => !model.SelectedCourses
.Contains(m.pkID))
.ToList()
.ForEach(m => student.Courses.Remove(m));
// Add newly selected items
var existingClientIds = student.Courses.Select(m => m.pkID).ToList();
db.Courses.Where(m => model.SelectedCourses.Except(existingClientIds)
.Contains(m.pkID))
.ToList()
.ForEach(m => student.Courses.Add(m));
db.students.Add(student);
db.SaveChanges();
return RedirectToAction("Index");
}
return View(student);
}
公共课堂学生课程视频模型
{
公立学生学生{get;set;}
公共IEnumerable AllCourses{get;set;}
私人名单(u selected course);;
公共选择课程列表
{
得到
{
如果(_selectedCourse==null)
{
_selectedCourse=Student.Courses.Select(m=>m.pkID.ToList();
}
返回所选课程;
}
设置{u selectedCourse=value;}
}
公共操作结果创建()
{
ViewBag.Courses=新的选择列表(db.Courses,“pkID”,“Name”);
返回视图();
}
公共操作结果创建(StudentCourseView模型,[Bind(Include=“pkID,Name”)]Student-Student)
{
if(ModelState.IsValid)
{
如果(学生==null)
返回HttpNotFound();
//删除未选中的项目
db.Courses.Where(m=>!model.SelectedCourses
.Contains(m.pkID))
托利斯先生()
.ForEach(m=>student.Courses.Remove(m));
//添加新选择的项目
var existingClientIds=student.Courses.Select(m=>m.pkID.ToList();
db.Courses.Where(m=>model.SelectedCourses.Except(existingclientId)
.Contains(m.pkID))
托利斯先生()
.ForEach(m=>student.Courses.Add(m));
db.students.Add(学生);
db.SaveChanges();
返回操作(“索引”);
}
返回视图(学生);
}
我现在想知道如何处理//GET:/Create
和//POST:/Create
以及如何在create.cshtml
中查看课程列表?
我在上面的代码中得到以下错误:
EntityFramework.dll中出现“System.Data.Entity.Infrastructure.DbUpdateException”类型的异常,但未在用户代码中处理
其他信息:更新条目时出错。有关详细信息,请参阅内部异常
保存多对多关系可能有点棘手,因为如果您不小心,EF可能会感到困惑,认为您试图读取现有项目,并给您完整性错误 您已经在使用一个视图模型,该模型的属性包含一个整数列表。这很好。成功了一半。现在,您只需要一些逻辑来查询所选课程并将其添加到
课程
集合:
// Remove items that were unselected
db.Courses.Where(m => !model.SelectedCourse.Contains(m.Id)).ToList()
.ForEach(m => student.Courses.Remove(m));
// Add newly selected items
var existingCourseIds = student.Courses.Select(m => m.Id).ToList();
db.Courses.Where(m => model.SelectedCourse.Except(existingCourseIds).Contains(m.Id)).ToList()
.ForEach(m => student.Courses.Add(m));
从技术上讲,只有在编辑现有学生时才有必要这样做。在创建或编辑中使用相同的代码不会有什么坏处,但在创建中可以简化为:
student.Courses = db.Courses.Where(m => model.SelectedCourse.Contains(m.Id));
由于您正在创建一个全新的学生,因此不需要担心现有的关系。关系在数据库中是如何映射的,您是否有一个中间的
StudentCourse
映射表?不清楚您的“视图模型”是如何映射的会以任何方式映射关系。嘿,我在数据库中有一个中间StudentCourse表,但当我创建.edmx时,StudentCourse表没有显示在模型中,而是一个带有“*”的多对多链接符号。听起来好像它已经正确映射了,您没有得到为中间表生成的类。ef只是填充相关的导航属性。您在控制器/视图中遇到了什么问题?我在创建新学生时用其他词更新学生时遇到了问题。我添加了以下内容要获取/创建函数ViewBag.Courses=new SelectList(db.Courses,“pkID”,“Name”);并且它可以工作,我在create视图中获得了一个列表,我可以选择,下面是如何修改Post/create函数以正确保存它的问题?谢谢Chris,我已经添加了ViewBag.Courses=new SelectList(db.Courses,“pkID”,“Name”);
到get/create函数,它在create视图中提供了一个可供选择的课程列表。现在,当我选择一个课程并键入create时,我在db.SaveChanges()行上遇到了错误;
,这是因为提取的数据与数据库不匹配,所以我不知道如何解决这个问题,我是否应该将StudentCourseViewModel参数传递给post/create函数?以及如何修复关系并保存?我不明白。也许,用现有代码更新您的问题,并包括c感谢你的行为。哦,我知道这不是很容易解释的,我现在用代码更新了问题。我的问题是我不明白如何处理多对多关系,我无法找到一个好的解释,首先是数据库,我找到了代码。