sql >> Databáze >  >> RDS >> Sqlserver

Entity Framework nefunguje s časovou tabulkou

Existují dvě řešení tohoto problému:

  1. V okně vlastností pro sloupec v návrháři EDMX změňte StoreGeneratedPattern v PERIOD sloupce (ValidFrom a ValidTo v mém případě) být identity . Identita je lepší než vypočítaná, protože vypočítaná způsobí, že EF obnoví hodnoty ve vložení a aktualizaci, na rozdíl od pouhé vložky s identity
  2. Vytvořte IDbCommandTreeInterceptor implementace k odstranění sloupců období. Toto je mé preferované řešení, protože nevyžaduje žádnou další práci při přidávání nových tabulek do modelu.

Zde je moje implementace:

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

Zaregistrujte tento interceptor u EF spuštěním následujícího kdekoli v kódu, než použijete kontext:

DbInterception.Add(new TemporalTableCommandTreeInterceptor());


  1. Může INNER JOIN nabídnout lepší výkon než EXISTS

  2. MySQL načte hodnoty NULL z dat CSV

  3. Jak ASIN() funguje v MariaDB

  4. Seznámení s možnostmi a funkcemi v MariaDB SkySQL