Reputation: 1070
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.
The information that I want to store is
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.
How shall I proceed in this case. Thanks in advance.
Upvotes: 2
Views: 849
Reputation: 37760
You can observe change tracker before SaveChanges
, and store changes in your own model. Later, use this model to to playback reversal actions.
E.g., 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.
Upvotes: 3