Добавить дополнительную команду базы данных с перехватчиком Entity Framework CommandTree

Я пытаюсь реализовать проверяемое хранилище данных в Entity Framework. Мое намерение состоит в том, чтобы вести историю состояния каждой записи в любой момент времени. Это требует, чтобы я преобразовывал все операторы удаления в обновления и все операторы обновления в обновление + вставку.

Я следил за сеансом обратимого удаления EF6 TechEd 2014, чтобы узнать об основных настройку перехватчика, но я дошел до того, что не знаю, как действовать дальше. У меня есть допустимые случаи для запроса, удаления и вставки, но обновление — это сложно.

Вот основная структура метода:

public void TreeCreated(DbCommandTreeInterceptionContext interceptionContext)
{
    if (interceptionContext.OriginalResult.DataSpace == DataSpace.SSpace)
    {
        //other query interceptors

        var updateCommand = interceptionContext.OriginalResult as DbUpdateCommandTree;
        if (updateCommand != null)
        {
            //I modify the command to soft delete the current record
            //(This is pseudo code to replace to verbose EF exp builder code)
            var newClause = GetNewSoftDeleteClause(updateCommand);
            interceptionContext.Result = GetUpdateCommandTree(updateCommand, newClause);

            //Here is where I want to insert a new command into the tree
            //and copy over the data to a new record
        }
    }
}

Насколько я могу судить, текущий Result можно изменить в методе TreeCreated, но я не могу найти способ вставить новую команду в контекст. Поскольку перехватчик работает только с одной строкой, я начинаю думать, что то, что я хочу сделать, невозможно в рамках метода TreeCreated.

Есть ли способ выполнить то, что я хочу сделать, используя перехватчики, не прибегая к триггерам базы данных?


person Timothy McLane    schedule 09.06.2014    source источник


Ответы (1)


В этом случае вы можете перезаписать savechanges() в своем AppicationDbContext. Вы можете использовать встроенное свойство ChangeTracker, чтобы найти объект, который будет обновляться, а затем прикрепить новый объект, который необходимо вставить.

 public override int SaveChanges()
    {
        List<DbEntityEntry> dbEntityEntries= ChangeTracker.Entries()
                .Where(e => e.Entity is Person && e.State == EntityState.Modified)
                .ToList()

        foreach(var dbEntityEntrie in dbEntityEntries)
        {
             var person = (Person)addedCourse.Entity;
             var log= new Log()
               {
                   Name=person.Name;
               }
             Logs.Add(log);
        }

        return base.SaveChanges();
    }

Вы можете реорганизовать этот код, используя Inheritance и Generics.

person Milina Udara    schedule 10.01.2015