简体   繁体   English

将对数据库所做的更改存储在Entity Framework中

[英]Store the changes done to database in Entity Framework

I want to store the changes done to database in a structure or something so that I can refer them anytime after the database context is over. 我想将对数据库所做的更改存储在结构或其他内容中,以便在数据库上下文结束后随时可以引用它们。 I am using Entity Framework in C# and underlying database in SQL Server. 我在C#中使用实体框架,在SQL Server中使用基础数据库。

The information that I want to store is 我要存储的信息是

  • The executing database context 正在执行的数据库上下文
  • The table name 表名
  • Previous value of updated column 更新列的先前值
  • New value of updated column 更新列的新值
  • Id of row added or deleted. 添加或删除的行ID。
  • operation performed( update or delete or add ) 执行的操作(更新或删除或添加)

Currently I am storing them in form of string. 目前,我以字符串形式存储它们。 But the problem is, using this approach I can not reproduce the linq query so that I can revert the changes. 但是问题是,使用这种方法,我无法重现linq查询,因此我可以还原更改。

How shall I proceed in this case. 在这种情况下,我该如何进行。 Thanks in advance. 提前致谢。

You can observe change tracker before SaveChanges , and store changes in your own model. 您可以在SaveChanges之前观察变更跟踪器 ,并将变更存储在自己的模型中。 Later, use this model to to playback reversal actions. 以后,使用此模型来播放撤消操作。

Eg, given this context: 例如,在这种情况下:

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

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

you can write such a class: 您可以编写这样的类:

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

and use it like this: 并像这样使用它:

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

Of course, universal solution will be more complex, but this should give you basic idea. 当然,通用解决方案会更复杂,但这应该给您基本的想法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM