Entity framework 使用实体框架处理并发性的最佳方法

Entity framework 使用实体框架处理并发性的最佳方法,entity-framework,ado.net,concurrency,entity-framework-4.1,Entity Framework,Ado.net,Concurrency,Entity Framework 4.1,我正在使用EntityFramework 4.1。使用EntityFramework处理并发性的最佳方法是什么。在实体框架中是否有处理它的内置功能? 我可以不向表中添加额外的列来保持行版本吗?您可以在表中设置一个名为RowVersion的列,并告诉Entity Framework您希望将该列包含在所有UPDATE和DELETE语句的where子句中。然后确保为所有更改的实体递增此字段。我是这样做的: //make all entities that need concurrency implem

我正在使用EntityFramework 4.1。使用EntityFramework处理并发性的最佳方法是什么。在实体框架中是否有处理它的内置功能?
我可以不向表中添加额外的列来保持行版本吗?

您可以在表中设置一个名为RowVersion的列,并告诉Entity Framework您希望将该列包含在所有UPDATE和DELETE语句的where子句中。然后确保为所有更改的实体递增此字段。我是这样做的:

//make all entities that need concurrency implement this and have RowVersion field in database
public interface IConcurrencyEnabled
{
    int RowVersion { get; set; }
}
public class MyDbContext : DbContext
{
    public override int SaveChanges()
    {
        foreach(var dbEntityEntry in ChangeTracker.Entries().Where(x => x.State == EntityState.Added || x.State == EntityState.Modified))
        {
            IConcurrencyEnabled entity = dbEntityEntry.Entity as IConcurrencyEnabled;
            if (entity != null)
            {
                entity.RowVersion = entity.RowVersion + 1;
            }
        }
        return base.SaveChanges();
    }
    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);
        //do all your custom model definition but have the following also:
        modelBuilder.Entity<myEntity>().Property(x => x.RowVersion).IsConcurrencyToken();
    }
}
//使所有需要并发的实体都实现此功能,并在数据库中具有RowVersion字段
公共接口IConcurrencyEnabled
{
int行版本{get;set;}
}
公共类MyDbContext:DbContext
{
公共覆盖int SaveChanges()
{
foreach(ChangeTracker.Entries()中的var dbEntityEntry,其中(x=>x.State==EntityState.Added | | x.State==EntityState.Modified))
{
IConcurrencyEnabled entity=dbEntityEntry。实体为IConcurrencyEnabled;
如果(实体!=null)
{
entity.RowVersion=entity.RowVersion+1;
}
}
返回base.SaveChanges();
}
模型创建时受保护的覆盖无效(DbModelBuilder modelBuilder)
{
基于模型创建(modelBuilder);
//执行所有自定义模型定义,但也要具有以下内容:
modelBuilder.Entity().Property(x=>x.RowVersion).IsConcurrencyToken();
}
}

您看过本教程吗:


您可以在不使用rowversion列的情况下执行此操作,但这通常需要存储大量状态,这会对性能产生不利影响。

我阅读了此问题。它有一个不同的想法,谢谢,没有行版本列不行吗?我想您可以使用
IsConcurrencyToken()
设置多个属性,EF将在update和delete语句的where子句中添加这些列。我还没有测试过这个,是的,它可以使用多个属性作为并发令牌,我只是在一个情况下测试过它。所有并发属性都包含在WHERE子句中。谢谢,因为我发现我们需要一个小的更改来确保新记录的行版本设置为1:if(dbEntityEntry.State==EntityState.Added)entity.RowVersion=1;如果(dbEntityEntry.State==EntityState.Modified)entity.RowVersion=entity.RowVersion+1;