将完成的更改存储在Entity Framework中

时间:2016-03-02 07:34:19

标签: c# sql-server entity-framework linq

我想将对数据库所做的更改存储在结构或其他内容中,以便我可以在数据库上下文结束后随时引用它们。我在C#中使用Entity Framework,在SQL Server中使用底层数据库。

我要存储的信息是

  • 正在执行的数据库上下文
  • 表名
  • 更新列的上一个值
  • 更新列的新值
  • 添加或删除行的ID。
  • 执行的操作(更新或删除或添加)

目前我以字符串的形式存储它们。但问题是,使用这种方法我无法重现linq查询,以便我可以还原更改。

在这种情况下我该如何处理。提前致谢。

1 个答案:

答案 0 :(得分:2)

您可以在change tracker之前观察SaveChanges,并将更改存储在您自己的模型中。稍后,使用此模型播放反转动作。

,例如,鉴于此背景:

public class Person
{
    public int Id { get; set; }
    public string Name { get; set; }
}

public class SampleContext : DbContext
{
    public DbSet<Person> People { get; set; }
}

你可以写这样一堂课:

public class SampleContextMemento
{
    private IEnumerable<Person> addedPeople;
    private IEnumerable<Person> deletedPeople;

    private IEnumerable<T> GetEntitiesByState<T>(SampleContext context, EntityState state)
        where T : class
    {
        return context.ChangeTracker
            .Entries<T>()
            .Where(_ => _.State == state)
            .Select(_ => _.Entity)
            .ToList();
    }

    public void RecordChanges(SampleContext context)
    {
        addedPeople = GetEntitiesByState<Person>(context, EntityState.Added);
        deletedPeople = GetEntitiesByState<Person>(context, EntityState.Deleted);
    }

    public void RollbackChanges(SampleContext context)
    {
        // delete added entities
        if (addedPeople != null)
        {
            foreach (var item in addedPeople)
            {
                context.People.Remove(context.People.Find(item.Id));
            }
        }

        if (deletedPeople != null)
        {
            // add deleted entities
            foreach (var item in deletedPeople)
            {
                context.People.Add(item);
            }
        }

        // save reverted changes
        context.SaveChanges();
    }
}

并像这样使用它:

var memento = new SampleContextMemento();

// make changes
using (var context = new SampleContext())
{
    // add some entities
    context.People.Add(new Person { Id = 100, Name = "John" });
    // remove some
    context.People.Remove(context.People.Find(1));
    // saving changes in our memento to rollback them later
    memento.RecordChanges(context);
    context.SaveChanges();
}

// rollback them
using (var context = new SampleContext())
{
    memento.RollbackChanges(context);
}

当然,通用解决方案会更复杂,但这应该会给你基本的想法。