简体   繁体   English

实体框架:RowVersion值为null

[英]Entity Framework: RowVersion value is null

I am using Entity Framework 6.2.0 and a local MSSQL (MDF) database. 我正在使用Entity Framework 6.2.0和本地MSSQL(MDF)数据库。

I have several types that all descend from my main type "Entity" ("Table per Type" strategy is used). 我有几种类型都源自我的主要类型“实体”(使用“每种类型的表”策略)。 Now, I am trying to implement optimistic locking. 现在,我正在尝试实现乐观锁定。

In my EDMX file, I added a property RowVersion to Entity (a fixed length byte array of 8 bytes, in SQL-DB : "[RowVersion] binary(8) NOT NULL") and set the Concurrency mode of that proeprty to "Fixed". 在我的EDMX文件中,我向实体添加了属性RowVersion(在SQL-DB中为8字节的固定长度字节数组:“ [RowVersion] binary(8)NOT NULL”),并将该属性的并发模式设置为“固定”。 ”。 I flagged the property inside the Entity class with the "Timestamp" attribute: 我用“ 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; }
}

I also added code to OnModelCreating of my DBContext descendant to indicate RowVersion to be used: 我还向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();
    }

The problem: Upon insert of a new Product, an SQL error is thrown. 问题:插入新产品后,将引发SQL错误。 This is the unit test i am using: 这是我正在使用的单元测试:

    [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);
        };
    }

The innermost exception thrown: 引发的最内层异常:

System.Data.SqlClient.SqlException: Cannot insert the value NULL into column 'RowVersion', table 'P:\\VISUAL STUDIO\\PROJECTS\\RIGHTSMANAGER\\DATABASE\\RIGHTSMANAGER.MDF.RightsManager.EntitySet'; System.Data.SqlClient.SqlException:无法将值NULL插入表“ P:\\ VISUAL STUDIO \\ PROJECTS \\ RIGHTSMANAGER \\ DATABASE \\ RIGHTSMANAGER.MDF.RightsManager.EntitySet”的“ RowVersion”列中; column does not allow nulls. 列不允许为空。 INSERT fails. INSERT失败。

Obviously, EF is not filling in a value automatically, it's handling the field like any other one. 显然,EF不会自动填写值,它像处理其他字段一样处理该字段。 What am i missing here? 我在这里想念什么?

I think i misunderstood the IsRowVersion/Timestamp thing to be a database-agnostic one. 我认为我误解了IsRowVersion / Timestamp是数据库不可知的东西。 It seems that this whole mechanism only works if using the MSSQL-specific database field type "rowversion" when creating the table. 似乎只有在创建表时使用特定于MSSQL的数据库字段类型“ rowversion”时,整个机制才起作用。 All other databases such as Oracle, DB2 etc are not in scope. 所有其他数据库(例如Oracle,DB2等)不在范围内。

As I am trying to have DBMS neutrality in my project, I will have to manually implement such a feature with "IsConcurrencyToken". 当我试图在项目中保持DBMS中立性时,我将不得不使用“ IsConcurrencyToken”手动实现这种功能。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM