I’m working on a larger sample (I will write or do a screencast about this shortly) which uses a distributed solution with WCF and the Entity framework 4 Code-only approach. Doing this I wanted to add a Concurrency token so that EF would trap concurrency violations, e.g:
1. I fetch an object which becomes detached.
2. The same object (seen to business equality) gets fetched in some other part of the application.
We now have to different instances representing the same domain object.
3. The entity from step 2 is updated and persisted.
4. When the entity from step 1 is sent to the object context for update, EF uses the Concurrency token field and gets 0-rows affected.
How do I add an concurrency token?
1. Add a property in your entity, which is of datatype byte[].
2. Add mapping for the field, stating that the added field is the Concurrency token and of which type (timestamp or rowversion)
Since I want all my entities to have this I add the property to my Entity-baseclass. I also have defined a base mapping class that maps this and the Id property for my entities, so that I don’t have to specify this all the time.
The Entities
public abstract class Entity
{
public virtual int Id { get; set; }
public virtual byte[] ConcurrencyToken { get; set; }
}
[Serializable]
public class UserAccount
: Entity
{
public virtual string Username { get; set; }
public virtual string Password { get; set; }
public virtual string Email { get; set; }
public virtual string Firstname { get; set; }
public virtual string Lastname { get; set; }
}
The mappings
[Serializable]
public abstract class EntityMapping<TEntity> : EntityConfiguration<TEntity>
where TEntity : Entity
{
protected EntityMapping()
{
HasKey(u => u.Id);
Property(u => u.Id).IsIdentity();
Property(u => u.ConcurrencyToken)
.IsRequired()
.IsConcurrencyToken()
.HasStoreType("timestamp")
.StoreGeneratedPattern = StoreGeneratedPattern.Computed;
}
}
[Serializable]
public class UserAccountMapping : EntityMapping<UserAccount>
{
public UserAccountMapping()
{
Property(u => u.Email)
.IsRequired()
.IsNotUnicode()
.MaxLength = 150;
Property(u => u.Username)
.IsRequired()
.IsUnicode()
.MaxLength = 20;
Property(u => u.Password)
.IsRequired()
.IsUnicode()
.MaxLength = 20;
Property(u => u.Firstname)
.IsRequired()
.IsUnicode()
.MaxLength = 100;
Property(u => u.Lastname)
.IsRequired()
.IsUnicode()
.MaxLength = 100;
}
}
//Daniel
[...] Entity framework 4 – How-to reuse mappings and add a Concurrency token [...]