实体框架:RowVersion值为null

时间:2018-09-24 09:22:01

标签: c# entity-framework edmx optimistic-locking optimistic-concurrency

我正在使用Entity Framework 6.2.0和本地MSSQL(MDF)数据库。

我有几种类型都源自我的主要类型“实体”(使用“每种类型的表”策略)。现在,我正在尝试实现乐观锁定。

在我的EDMX文件中,我向实体添加了属性RowVersion(在SQL-DB中为8字节的固定长度字节数组:“ [RowVersion] binary(8)NOT NULL”),并设置了该属性的并发模式到“固定”。我用“ Timestamp”属性标记了Entity类中的属性:

[System.ComponentModel.DataAnnotations.Schema.Table("EntitySet", Schema = "RightsManager")]
public partial class Entity
{
    public int Id { get; set; }
    public string Name { get; set; }
    public System.DateTime ActiveFrom { get; set; }
    public Nullable<System.DateTime> ActiveUntil { get; set; }

    [System.ComponentModel.DataAnnotations.Timestamp]
    public byte[] RowVersion { get; set; }
}

我还在我的DBContext后代的OnModelCreating中添加了代码,以指示要使用的RowVersion:

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        Database.SetInitializer<RightsManagerContext>(null);            
        base.OnModelCreating(modelBuilder);
        modelBuilder.Entity<Entity>().Property(p => p.RowVersion).IsRowVersion();
        modelBuilder.Entity<Product>().Property(p => p.RowVersion).IsRowVersion();
    }

问题:插入新产品后,将引发SQL错误。这是我正在使用的单元测试:

    [TestMethod]
    public void TestCreateProduct()
    {
        using (var context = GetContext())
        {
            var newProduct = new Product
            {
                Name = "New product",
                ActiveFrom = DateTime.Now

            };
            context.Entry(newProduct).State = System.Data.Entity.EntityState.Added;
            var objectsWritten = context.SaveChanges();
            Assert.AreNotEqual(0, objectsWritten);
        };
    }

引发的最内部异常:

  

System.Data.SqlClient.SqlException:无法将值NULL插入表'P:\ VISUAL STUDIO \ PROJECTS \ RIGHTSMANAGER \ DATABASE \ RIGHTSMANAGER.MDF.RightsManager.EntitySet'的'RowVersion'列中;列不允许为空。 INSERT失败。

很显然,EF不会自动填充值,它像处理其他字段一样处理该字段。我在这里想念什么?

1 个答案:

答案 0 :(得分:2)

我认为我误解了IsRowVersion / Timestamp是数据库不可知的东西。似乎只有在创建表时使用特定于MSSQL的数据库字段类型“ rowversion”时,整个机制才起作用。所有其他数据库(例如Oracle,DB2等)不在范围内。

当我试图在项目中保持DBMS中立性时,我将不得不使用“ IsConcurrencyToken”手动实现这种功能。