2016-03-02 29 views
0

我想将对数据库所做的更改存储在某个结构中,以便在数据库上下文结束后随时引用它们。我在C#中使用实体框架,并在SQL Server中使用底层数据库。将对数据库所做的更改存储在实体框架中

,我想存储的信息是

  • 的执行数据库上下文
  • 表名
  • 上更新的列的值
  • 更新列的新值
  • 行标识添加或删除。
  • 进行操作(更新或删除或添加)

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

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

+0

您可以观察更改跟踪器(请参阅https://msdn.microsoft.com/en-us/library/system.data.entity.dbcontext.changetracker%28v=vs.113%29.aspx#P:System。 Data.Entity.DbContext.ChangeTracker),然后收集新添加的项目的ID,然后在您自己的模型中收集此信息以便稍后回放反转操作。 – Dennis

+0

@ Dennis在上下文(SaveChanges)结束之后是否可以使用更改跟踪器? –

+0

'SaveChanges'重置更改跟踪器状态(即丢弃旧的更改数据)。当然,你可以在SaveChanges后访问它,但它将是“空的”。 – Dennis

回答

2

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

例如,鉴于这种情况下:

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

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

+0

如果我想在范围结束后执行此操作,该怎么办。即在关闭大括号之后。我怎么能再次获得上下文。 –

+0

@MadhurMaurya:我已经更新了答案。这一个适用于上下文的不同实例。 – Dennis

相关问题