Има две решения на този проблем:
- В прозореца на свойствата за колоната в EDMX дизайнера променете
StoreGeneratedPattern
наPERIOD
колони (ValidFrom и ValidTo в моя случай) да бъдатidentity
. Идентичността е по-добра от изчислената, тъй като изчислената ще накара EF да опресни стойностите при вмъкване и актуализиране, за разлика от просто вмъкване сidentity
- Създайте
IDbCommandTreeInterceptor
изпълнение за премахване на колоните за период. Това е моето предпочитано решение, тъй като не изисква допълнителна работа при добавяне на нови таблици към модела.
Ето моята реализация:
using System.Data.Entity.Infrastructure.Interception;
using System.Data.Entity.Core.Common.CommandTrees;
using System.Data.Entity.Core.Metadata.Edm;
using System.Collections.ObjectModel;
internal class TemporalTableCommandTreeInterceptor : IDbCommandTreeInterceptor
{
private static readonly List<string> _namesToIgnore = new List<string> { "ValidFrom", "ValidTo" };
public void TreeCreated(DbCommandTreeInterceptionContext interceptionContext)
{
if (interceptionContext.OriginalResult.DataSpace == DataSpace.SSpace)
{
var insertCommand = interceptionContext.Result as DbInsertCommandTree;
if (insertCommand != null)
{
var newSetClauses = GenerateSetClauses(insertCommand.SetClauses);
var newCommand = new DbInsertCommandTree(
insertCommand.MetadataWorkspace,
insertCommand.DataSpace,
insertCommand.Target,
newSetClauses,
insertCommand.Returning);
interceptionContext.Result = newCommand;
}
var updateCommand = interceptionContext.Result as DbUpdateCommandTree;
if (updateCommand != null)
{
var newSetClauses = GenerateSetClauses(updateCommand.SetClauses);
var newCommand = new DbUpdateCommandTree(
updateCommand.MetadataWorkspace,
updateCommand.DataSpace,
updateCommand.Target,
updateCommand.Predicate,
newSetClauses,
updateCommand.Returning);
interceptionContext.Result = newCommand;
}
}
}
private static ReadOnlyCollection<DbModificationClause> GenerateSetClauses(IList<DbModificationClause> modificationClauses)
{
var props = new List<DbModificationClause>(modificationClauses);
props = props.Where(_ => !_namesToIgnore.Contains((((_ as DbSetClause)?.Property as DbPropertyExpression)?.Property as EdmProperty)?.Name)).ToList();
var newSetClauses = new ReadOnlyCollection<DbModificationClause>(props);
return newSetClauses;
}
}
Регистрирайте този прехващач с EF, като изпълните следното навсякъде в кода си, преди да използвате своя контекст:
DbInterception.Add(new TemporalTableCommandTreeInterceptor());