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?
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.
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.
I am new to EF and I had the same problem. In my storage program i e.g sumit only articleId and OwnerId for a new stock because i see no need for hidden fields in my mvc-form. At first EF created new entries in article and customer database, but i only wanted to insert a new item in the stocks table. So the solution is quite simple: For all entities you know you don´t want to save them type this:
//prevent Owner to be saved (again)
db.Entry(stockItem.Owner).State = EntityState.Unchanged;
//prevent article to be saved (again)
db.Entry(stockItem.ArticleItem).State = EntityState.Unchanged;
db.Stocks.Add(stockItem);
//now just the properties (-> dbset of the stockItem get´s saved)
await db.SaveChangesAsync();
return RedirectToAction("Index");
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With