Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Simple Edit/Update actions using LINQ. Isn't my code a bit wrong?

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?

like image 623
alex2k8 Avatar asked Nov 27 '25 22:11

alex2k8


1 Answers

This is Linq checking for database concurrency. You can suppress this behavior by setting this attribute on your columns:

[Column(... UpdateCheck=UpdateCheck.Never)]

More details here: http://msdn.microsoft.com/en-us/library/bb399373.aspx.

like image 144
Keltex Avatar answered Nov 30 '25 08:11

Keltex



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!