我认为这些方法本质上是相同的,但第一个方法首先查询数据库,因此由于击中数据库两次而导致性能降低。我最多只有40个用户,所以性能不是太大的问题。有没有其他理由使用其中一个?
首先从数据库中抓取实体,更改它然后保存它:
public void UpdateStudent(StudentModel model)
{
using (var _db = new AppEntities())
{
Student student = new Student();
student = _db.Student.Find(model.studentId);
student.FirstName = model.FirstName;
student.LastName = model.LastName;
student.DOB = model.DOB;
student.GradeId = model.GradeId;
_db.Entry(student).State = System.Data.Entity.EntityState.Modified;
_db.SaveChanges();
}
}
更改实体,让EF在数据库中找到它并更新:
public void UpdateStudent(StudentModel model)
{
using (var _db = new AppEntities())
{
Student student = new Student()
{
student.StudentId = model.StudentId,
student.FirstName = model.FirstName,
student.LastName = model.LastName,
student.DOB = model.DOB,
student.GradeId = model.GradeId
};
_db.Entry(student).State = System.Data.Entity.EntityState.Modified;
_db.SaveChanges();
}
}
答案 0 :(得分:1)
在第一个代码段中,您将获取某个版本的实体表单db。如果其他线程或进程修改了同一个实体,我不认为EF会让你只是进行更新,因为你的基本版本的实体与更新查询之前的数据库中的实体不同。
在第二个中,如果某个线程或进程在您处理此请求时修改了该实体,则可能会丢失该更改。
编辑:我从不厌倦。我总是得到实体,然后修改并保存,但你可以写一个测试来验证发生了什么。答案 1 :(得分:1)
在您的第一个代码段中,您不必将实体标记为Modified
,因为更改跟踪器会处理此问题。这一点很重要,因为它还定义了两种方法之间的差异。我会解释一下。
让我们假设所有作业(student.FirstName = model.FirstName;
等)只有第一个是真正的改变。如果是的话 -
Modified
)会触发仅更新FirstName
的更新语句。Student
中所有字段。这意味着第一个片段不太可能导致并发冲突(其他人可能会同时更改LastName
并且您不会通过陈旧数据覆盖此修改,如第二个场景中所发生的那样)。
所以它涉及细粒度的变化与全面的更新,往返与冗余:
由您来平衡权衡取舍。
为了让这个选择更加困难,还有第三个选择:
public void UpdateStudent(StudentModel model)
{
using (var _db = new AppEntities())
{
Student student = new Student()
{
student.StudentId = model.StudentId,
student.FirstName = model.FirstName,
student.LastName = model.LastName,
student.DOB = model.DOB,
student.GradeId = model.GradeId
};
_db.Students.Attach(student);
_db.Entry(student).Property(s => s.FirstName).IsModified = true;
_db.Entry(student).Property(s => s.LastName).IsModified = true;
_db.Entry(student).Property(s => s.DOB).IsModified = true;
_db.Entry(student).Property(s => s.GradeId).IsModified = true;
_db.SaveChanges();
}
}
没有往返,现在您只将4个属性标记为已修改。因此,如果实际只更改了一个属性,您仍然会更新太多属性,但是四个属性比所有属性更好。
此外还有更多" rondtrips vs redundancy"问题,但我解释了elswhere。