开发者

How to leverage concurrency checking with EF 4.0 POCO Self Tracking Entities in a N-Tier scenario?

I'm using VS1010RC with the POCO self tracking T4 templates.

In my WCF update service method I am using something similar to the following:

using (var context = new MyContext())
{
  context.MyObjects.ApplyChanges(myObject);
  context.SaveChanges();
}

This works fine until I set ConcurrencyMode=Fixed on the entity and then I get an exc开发者_如何学JAVAeption. It appears as if the context does not know about the previous values as the SQL statement is using the changed entities value in the WHERE clause.

What is the correct approach when using ConcurrencyMode=Fixed?


The previous values need to be in your object.

Let's say you have a property ConcurrencyToken:

public class MyObject
{
    public Guid Id { get; set; }
    // stuff
    public byte[] ConcurrencyToken { get; set; }
}

Now you can set ConcurrencyMode.Fixed on that property. You also need to configure your DB to automatically update it.

When you query the DB, it will have some value:

var mo = Context.MyObjects.First();
Assert.IsNotNull(mo.ConcurrencyToken);

Now you can detach or serialize the object, but you need to include ConcurrencyToken. So if you're putting the object data on a web form, you'll need to serialize ConcurrencyToken to a string and put it in a hidden input.

When you ApplyChanges, you need to include the ConcurrencyToken:

Assert.IsNotNull(myObject.ConcurrencyToken);
using (var context = new MyContext())
{
  context.MyObjects.ApplyChanges(myObject);
  context.SaveChanges();
}

Having ConcurrencyMode.Fixed changes the UPDATE SQL. Normally it looks like:

UPDATE [dbo].[MyObject]
SET --stuff
WHERE [Id] = @0

With ConcurrencyMode.Fixed it looks like:

UPDATE [dbo].[MyObject]
SET --stuff
WHERE [Id] = @0 AND [ConcurrencyToken] = @1

...so if someone has updated the row between the time you read the original concurrency token and the time you saved, the UPDATE will affect 0 rows instead of 1. The EF throws a concurrency error in this case.

Therefore, if any of this isn't working for you, the first step is to use SQL Profiler to look at the generated UPDATE.


Mark,

The objects created as "Self-tracking entities" cannot be considered pure POCOs;

Here's the reason: The STEs only work well if your client uses the generated proxies from the STE T4 template. Change-tracking, and thus your service, will only work with these generated proxies.

In a pure POCO world (interoperatibility, Not all .Net 4.0 clients, .. ), you cannot put constraints on you client. For instance, facebook will not be writing a service that can only handle .Net 4.0 clients.

STEs may be a good choice in some environments, it all depends on your requirements.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜