简体   繁体   中英

Entity Framework: RowVersion value is null

I am using Entity Framework 6.2.0 and a local MSSQL (MDF) database.

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". I flagged the property inside the Entity class with the "Timestamp" attribute:

[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:

    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. 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'; column does not allow nulls. INSERT fails.

Obviously, EF is not filling in a value automatically, it's handling the field like any other one. What am i missing here?

I think i misunderstood the IsRowVersion/Timestamp thing to be a database-agnostic one. It seems that this whole mechanism only works if using the MSSQL-specific database field type "rowversion" when creating the table. All other databases such as Oracle, DB2 etc are not in scope.

As I am trying to have DBMS neutrality in my project, I will have to manually implement such a feature with "IsConcurrencyToken".

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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