sql >> Database >  >> RDS >> Sqlserver

Entity Framework werkt niet met tijdelijke tabel

Er zijn twee oplossingen voor dit probleem:

  1. In het eigenschappenvenster voor de kolom in de EDMX-ontwerper wijzigt u het StoreGeneratedPattern op de PERIOD kolommen (ValidFrom en ValidTo in mijn geval) als identity . Identiteit is beter dan berekend, omdat berekend EF ertoe zal brengen de waarden op een Insert en Update te vernieuwen in plaats van alleen een insert met identity
  2. Maak een IDbCommandTreeInterceptor implementatie om de periodekolommen te verwijderen. Dit is mijn voorkeursoplossing omdat het geen extra werk vereist bij het toevoegen van nieuwe tabellen aan het model.

Dit is mijn implementatie:

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

Registreer deze interceptor bij EF door het volgende ergens in uw code uit te voeren voordat u uw context gebruikt:

DbInterception.Add(new TemporalTableCommandTreeInterceptor());


  1. SQLiteConstraintException-fout die wordt weergegeven na het starten van elke activiteit

  2. Hoe vervang ik een reguliere expressie in MySQL?

  3. 'SQLSTATE[HY093]:Ongeldig parameternummer:aantal gebonden variabelen komt niet overeen met aantal tokens'

  4. Stel startwaarde in voor kolom met autoincrement