Sqlserver
 sql >> Baza danych >  >> RDS >> Sqlserver

Entity Framework nie działa z tabelą czasową

Istnieją dwa rozwiązania tego problemu:

  1. W oknie właściwości kolumny w projektancie EDMX zmień StoreGeneratedPattern w PERIOD kolumny (ValidFrom i ValidTo w moim przypadku) mają być identity . Tożsamość jest lepsza niż obliczona, ponieważ obliczona spowoduje, że EF odświeży wartości na wstawieniu i aktualizacji, a nie tylko wstawieniu z identity
  2. Utwórz IDbCommandTreeInterceptor wdrożenie, aby usunąć kolumny okresu. To jest moje preferowane rozwiązanie, ponieważ nie wymaga dodatkowej pracy przy dodawaniu nowych tabel do modelu.

Oto moja implementacja:

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

Zarejestruj ten przechwytywacz za pomocą EF, uruchamiając w dowolnym miejscu kodu przed użyciem kontekstu:

DbInterception.Add(new TemporalTableCommandTreeInterceptor());


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Nie można znaleźć pliku microsoft.sqlserver.batchparser.dll

  2. Jak połączyć serwer sql z php za pomocą xampp?

  3. Skrypt całej bazy danych SQL-Server

  4. Jak uzyskać aktualną datę w SQL Server

  5. Sekwencja a tożsamość