Я использую Entity Framework 6.2.0 и локальную базу данных MSSQL (MDF).
У меня есть несколько типов, которые происходят от моего основного типа "Сущность" (используется стратегия "Таблица на тип"). Теперь я пытаюсь реализовать оптимистическую блокировку.
В моем файле EDMX я добавил свойство RowVersion в Entity (байтовый массив фиксированной длины из 8 байтов, в SQL-DB: «[RowVersion] binary(8) NOT NULL») и установил для режима параллелизма этого свойства значение «Fixed ". Я пометил свойство внутри класса Entity атрибутом «Timestamp»:
[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; }
}
Я также добавил код в OnModelCreating моего потомка DBContext, чтобы указать, что 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 в столбец «RowVersion», таблица «P:\VISUAL STUDIO\PROJECTS\RIGHTSMANAGER\DATABASE\RIGHTSMANAGER.MDF.RightsManager.EntitySet»; столбец не допускает пустых значений. ВСТАВИТЬ не удается.
Очевидно, что EF не заполняет значение автоматически, он обрабатывает поле, как и любое другое. Что мне здесь не хватает?