我使用的是EF4,并且在更新和删除项目时遇到问题。 我对插入很满意,但更新和删除无法弄明白。
假设我有3个表和3个匹配的dto类
ClassRoom表
ClassID-ClassName
学生表
StudentID-StudentName
StudentClass表
StudentID-ClassID
///Happy all works I am using existing students to populate the class. Fine.
private void InsertClassRoom(ClassRoomDto classRoomDto)
{
using (var ctx = new TrainingContext())
{
//Convert dto to Entity
var classRoomEntity = new ClassRoom { ClassID = classRoomDto.ClassId, ClassName = classRoomDto.ClassName };
foreach (var studentInClass in classRoomDto.Students)
{
Student student = ctx.Students.Where(x => x.StudentID == studentInClass.StudentId).SingleOrDefault();
classRoomEntity.Students.Add(student);
}
ctx.AddToClassRooms(classRoomEntity);
ctx.SaveChanges();
}
}
但我有2个场景无法弄清楚该怎么做。
从班级中删除学生 我该怎么做?
这是我的更新尝试:
private void UpdateClassRoom(ClassRoomDto classRoomDto)
{
using (var ctx = new TrainingContext())
{
var classRoomEntity = new ClassRoom { ClassID = classRoomDto.ClassId, ClassName = classRoomDto.ClassName };
foreach (var studentDto in classRoomDto.Students)
{
if (studentDto.StudentId == 0)
{
//it's a new student add it to the classroom
Student student = new Student { StudentID = studentDto.StudentId, StudentName = studentDto.StudentName };
classRoomEntity.Students.Add(student);
}
else
{
//Alter name of the student
Student student = ctx.Students.Where(x => x.StudentID == studentDto.StudentId).SingleOrDefault();
//update name
student.StudentName = studentDto.StudentName;
//? what do I do finish this attach or ???
}
}
ctx.AddToClassRooms(classRoomEntity);
ctx.SaveChanges();
}
}
public void DeleteStudent(ClassRoomDto classRoomDto)
{
using (var ctx = new TrainingContext())
{
//lost on how to delete a student in many to many
}
}
答案 0 :(得分:11)
首先,我假设你知道教室已经存在于数据库中。最简单的方法是首先查询它。您实际插入新ClassRoom
条目的原因是您使用ctx.AddToClassRooms(classRoomEntry)
。这会将实体附加到上下文,并将EntityState
设置为Added
。
private void UpdateClassRoom(ClassRoomDto classRoomDto)
{
using (var ctx = new TrainingContext())
{
ClassRoom classRoomEntity = ctx.
ClassRooms.
Include("Students").
Single(c => c.ClassID == classRoomDto.ClassId);
classRoomEntity.ClassName = classRoomDto.ClassName;
foreach (var studentDto in classRoomDto.Students)
{
if (studentDto.StudentId == 0)
{
// it's a new student add it to the classroom
Student student = new Student
{
StudentID = studentDto.StudentId,
StudentName = studentDto.StudentName
};
classRoomEntity.Students.Add(student);
}
else
{
// Student exists in the DB, but you don't know whether it's
// already part of the student collection for the classroom
Student student = classRoomEntity.
Students.
FirstOrDefault(s => s.StudentID == studentDto.StudentId);
if (student == null)
{
// this student is not in the class, fetch it from the DB
// and add to the classroom
student = ctx.
Students.
SingleOrDefault(s => s.StudentID == studentDto.StudentId)
classRoomEntity.Students.Add(student);
}
// Update name
student.StudentName = studentDto.StudentName;
// Since student is now part of the classroom student collection
// and classroom IS attached => student is also attached
}
}
ctx.SaveChanges();
}
}
为了从thr课程中删除学生,您只需将其从集合中删除(但不要调用ctx.DeleteObject()
,因为这会将学生从数据库中删除在你的情况下,上面的代码不会处理这个问题,因为它只会增加新的学生。而不是匹配数据库中的所有学生,而不是你的DTO中的学生,你可以采取一种更简单的方法。清除列表首先,然后添加学生:
private void UpdateClassRoom(ClassRoomDto classRoomDto)
{
using (var ctx = new TrainingContext())
{
ClassRoom classRoomEntity = ctx.
ClassRooms.
Include("Students").
Single(c => c.ClassID == classRoomDto.ClassId);
classRoomEntity.ClassName = classRoomDto.ClassName;
classRoomEntity.Students.Clear();
foreach (var studentDto in classRoomDto.Students)
{
Student student;
if (studentDto.StudentId == 0)
{
// it's a new student add it to the classroom
student = new Student
{
StudentID = studentDto.StudentId,
StudentName = studentDto.StudentName
};
}
else
{
student = ctx.
Students.
SingleOrDefault(s => s.StudentID == studentDto.StudentId)
// Update name
student.StudentName = studentDto.StudentName;
}
classRoomEntity.Students.Add(student);
}
ctx.SaveChanges();
}
}
这可能是您正在寻找的方法。我特意编写了第一个代码片段,向您展示了如何处理新实体和现有实体的不同情况,但这是第二种(更简单)方法更正确。希望这会有所帮助。