我想将对数据库所做的更改存储在某个结构中,以便在数据库上下文结束后随时引用它们。我在C#中使用实体框架,并在SQL Server中使用底层数据库。将对数据库所做的更改存储在实体框架中
,我想存储的信息是
- 的执行数据库上下文
- 表名
- 上更新的列的值
- 更新列的新值
- 行标识添加或删除。
- 进行操作(更新或删除或添加)
目前,我将它们存储在字符串的形式。但问题是,使用这种方法我无法重现linq查询,以便我可以恢复更改。
在这种情况下我应该如何处理。提前致谢。
我想将对数据库所做的更改存储在某个结构中,以便在数据库上下文结束后随时引用它们。我在C#中使用实体框架,并在SQL Server中使用底层数据库。将对数据库所做的更改存储在实体框架中
,我想存储的信息是
目前,我将它们存储在字符串的形式。但问题是,使用这种方法我无法重现linq查询,以便我可以恢复更改。
在这种情况下我应该如何处理。提前致谢。
您可以在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);
}
当然,通用的解决方案比较复杂,但是这应该给你基本的想法。
如果我想在范围结束后执行此操作,该怎么办。即在关闭大括号之后。我怎么能再次获得上下文。 –
@MadhurMaurya:我已经更新了答案。这一个适用于上下文的不同实例。 – Dennis
您可以观察更改跟踪器(请参阅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
@ Dennis在上下文(SaveChanges)结束之后是否可以使用更改跟踪器? –
'SaveChanges'重置更改跟踪器状态(即丢弃旧的更改数据)。当然,你可以在SaveChanges后访问它,但它将是“空的”。 – Dennis