0

I think these are essentially the same method, but the first one queries the db first, so has less performance due to hitting the db twice. I will only have 40 users at most so performance isn't too big an issue. Is there any other reason to use one over the other?

Grab the entity from the db first, change it then save it:

    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();
        }
    }

Change the entity and let EF find it in the DB and update:

    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();
        }
    }
BattlFrog
  • 3,370
  • 8
  • 56
  • 86

2 Answers2

1

In first code snippet you take some version of entity form db. If other thread or proccess modifies the same entity I don't think EF would let you just do an update as your base version of entity differs from that one in db right before an update query.

In the second one if some thread or process modifies this entity while you're processing this request you probably could lose that change.

EDIT: I never tired that. I'm always getting the entity and then modify and save but you could write a test to verify what happens.

1

In your first snippet, you don't have to mark the entity as Modified, because the change tracker takes care of that. This is important to note because it also defines the difference between the two methods. I'll explain.

Let's assume that of all assignments (student.FirstName = model.FirstName; etc.) only the first one is a real change. If so -

  • The first code fragment (but without marking the entity as Modified) triggers an update statement that only updates FirstName.
  • The second code fragment always updates all fields in Student.

This means that the first fragment is less likely to cause concurrency conflicts (someone else may change LastName in the mean time and you don't overwrite this modification by stale data, as happens in the second scenario).

So it's about fine-grained changes vs. a sweeping update, roundtrips vs. redundancy:

  • the first scenario takes roundtrips but is more concurrency-safe.
  • the second scenario takes no roundtrips but is less concurrency-safe.

It's up to you to balance the trade-offs.

To make this choice a little bit harder, there is a third option:

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();
    }
}

No roundtrip and now you only mark 4 properties as modified. So you still update too many properties if only one was actually changed, but four is better than all.

And there's more to this "rondtrips vs redundancy" question, but I explained that elswhere.

Community
  • 1
  • 1
Gert Arnold
  • 105,341
  • 31
  • 202
  • 291