2016-03-02 87 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

相關問題