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'm actually trying to do is send:
UPDATE [dbo].[Foos]
SET [P1] = @p1
WHERE ([Id] = @p0)
But actually we get 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 ensures that the object has not changed since the last query, but this is actually useless in our context. Indeed, db can be modified before the user submits the form, and our code does not detect any problems. But if Foo was changed after we read it in the Update action, but before SubmitChanges we get a ChangeConflictException (this will be confusing).
For such updates (checking the original db values), to make any sense, we need to send the original Foo object back and forward over HTTP.
public ActionResult Update(Foo original, Foo changed)
{
Foo foo = db.Foos.Attach(changed, original);
db.SubmitChanges();
}
db, .
, ?