Consider a simple Edit/Update code:
public ActionResult Edit(int id)
{
return View(db.Foos.Single(x => x.Id == id));
}
public ActionResult Update(Foo changed)
{
Foo foo = db.Foos.Single(x => x.Id == changed.Id);
foo.P1 = changed.P1;
db.SubmitChanges();
}
What I am actually trying to do here is to send:
UPDATE [dbo].[Foos]
SET [P1] = @p1
WHERE ([Id] = @p0)
But actually we end up with 2 db calls:
// Read current db object
SELECT [t0].[Id], [t0].[P1]
FROM [dbo].[Foos] AS [t0]
WHERE [t0].[Id] = @p0
// Submit changes
UPDATE [dbo].[Foos]
SET [P1] = @p2
WHERE ([Id] = @p0) AND ([P1] = @p1)
The UPDATE query makes sure the object did not change since last query, but actually this is useless in our context. Indeed, db could be changed before user submitted the form and our code will not detect any problems. But if Foo was changed after we read it in Update action, but before SubmitChanges, we'll receive ChangeConflictException (that would be confusing).
For such updates (checking original db values) to make any sence we should send original Foo object back and forward over HTTP.
public ActionResult Update(Foo original, Foo changed)
{
Foo foo = db.Foos.Attach(changed, original);
db.SubmitChanges();
}
In this case we will detect changes in db while user was entering values.
But if I don't care about concurrent changes, isn't original Update methods looks wrong?