使用Entity Framework CommandTree拦截器添加额外的数据库命令

时间:2014-06-09 19:26:08

标签: entity-framework entity-framework-6.1

我正在尝试在Entity Framework中实现可审核的数据存储区。我的目的是在任何给定的时间点记录每个记录的状态。这要求我将所有删除语句转换为更新,并将所有更新语句转换为update + insert。

我按照TechEd 2014 EF6 soft delete session视频进行了拦截器的基本设置,但是我已经到了一个我不确定如何继续的地方。我有查询,删除和插入的有效案例,但更新是棘手的。

以下是该方法的基本结构:

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方法中我不想做什么。

有没有办法在不使用数据库触发器的情况下使用拦截器完成我想做的事情?

1 个答案:

答案 0 :(得分:0)

在这种情况下,您可以覆盖AppicationDbContext中的savechanges()。您可以使用内置属性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();
    }

您可以使用继承和泛型重构此代码。