How can I tell Entity Framework to save changes only for a specific DbSet?

.net c# entity-framework

Question

Let's say I modify entities from different DbSets within a single DbContext.

How can I tell Entity Framework, when calling SaveChanges(), to save changes only for a specific DbSet?

1
10
10/29/2015 12:14:17 AM

Accepted Answer

Ideally, what you would do is just modify the entities you want to change, then call SaveChanges() then modify the other entities. However, if that is not possible I would add an overload of SaveChanges() that looks like this.

public int SaveChanges<TEntity>() where TEntity : class
{
    var original = this.ChangeTracker.Entries()
                .Where(x => !typeof(TEntity).IsAssignableFrom(x.Entity.GetType()) && x.State != EntityState.Unchanged)
                .GroupBy(x => x.State)
                .ToList();

    foreach(var entry in this.ChangeTracker.Entries().Where(x => !typeof(TEntity).IsAssignableFrom(x.Entity.GetType())))
    {
        entry.State = EntityState.Unchanged;
    }

    var rows = base.SaveChanges();

    foreach(var state in original)
    {
        foreach(var entry in state)
        {
            entry.State = state.Key;
        }
    }

    return rows;
}

Initially you find all entities whose state is not unchanged and save their entry. Then you set the state of every entity that isn't of your type TEntity and set their state to unchanged. Then call the base.SaveChanges() to save all changes to entities of your type.

Then, by looping through the saved entries, you can reset their original states back to them. This way you catch all adds/updates/deletes that aren't of your type, and restore them so that the next call to SaveChanges() doesn't lose their changes.

18
6/1/2018 5:21:17 PM

Popular Answer

Before using the below code, you should know if you want to save only a specific set of entities, then it means you should use different instance of your db context for that unit of your work.

But using this code you can reject changes of all entities except YourSpecialEntity:

db.ChangeTracker.Entries()
                .Where(x => x.State == EntityState.Modified &&
                            !typeof(YourSpecialEntity).IsAssignableFrom(x.Entity.GetType()))
                .ToList()
                .ForEach(entry => {
                    entry.CurrentValues.SetValues(entry.OriginalValues);
                });

db.SaveChanges();

I suppose db is an instance of your dbcontext.



Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow