I want to refresh all entities of my DbContext
without recreating it, I tried the following and none of them make sense:
var context = ((IObjectContextAdapter)myDbContext).ObjectContext;
var refreshableObjects = (from entry in context.ObjectStateManager.GetObjectStateEntries(
EntityState.Added
| EntityState.Deleted
| EntityState.Modified
| EntityState.Unchanged)
where entry.EntityKey != null
select entry.Entity);
context.Refresh(RefreshMode.StoreWins, refreshableObjects);
//.......................................................................
foreach (var entry in this.Orm.ChangeTracker.Entries())
{
entry.State = EntityState.Unchanged;
}
this.Orm.ChangeTracker.DetectChanges();
And the only one which refreshes my DbContext
:
foreach (var i in this.Orm.ChangeTracker.Entries())
i.Reload();
But it's too slow. Can you help me choosing the right way?
To refresh an entity definition: Right-click the Entities folder and select Refresh Entity.
//Get the object Product someProduct = someObjectContext. Product. First(); //At runtime at some point, recreate the ObjectContext someObjectContext = new SomeObjectContext(); //Try to refresh someProduct on the new ObjectContext someObjectContext. Refresh(RefreshMode.
This can be achieved in several ways: setting the EntityState for the entity explicitly; using the DbContext. Update method (which is new in EF Core); using the DbContext. Attach method and then "walking the object graph" to set the state of individual properties within the graph explicitly.
I just found that the Enumerable
result should be evaluated because the Refresh
method gets it as object and doesn't evaluate it.
var context = ((IObjectContextAdapter)myDbContext).ObjectContext; var refreshableObjects = (from entry in context.ObjectStateManager.GetObjectStateEntries( EntityState.Added | EntityState.Deleted | EntityState.Modified | EntityState.Unchanged) where entry.EntityKey != null select entry.Entity).ToList(); context.Refresh(RefreshMode.StoreWins, refreshableObjects);
And I prefer the following:
var refreshableObjects = myDbContext.ChangeTracker.Entries().Select(c=>c.Entity).ToList(); context.Refresh(RefreshMode.StoreWins, refreshableObjects);
I checked this and id works fine:
//Search
Box box = dbContext.Boxes.FirstOrDefault(x => x.BoxId == 45);
//breakpoint here, change Name of Box by sql management studio
//Refresh
var context = ((IObjectContextAdapter)dbContext).ObjectContext;
context.Refresh(System.Data.Entity.Core.Objects.RefreshMode.StoreWins, box);
//Check refresh and if it is in context
box = dbContext.Boxes.FirstOrDefault(x => x.BoxId == 45);
Are you sure it is the same db-context?
In some cases, if a collection has been updated by a third party app, the collection may not be reloaded when refreshing the collection's object.
I had the case where I had an object A with a one to many relashionship to an object B.
Application 1 loads an object A with A.ListB empty. Application 2 fills the A.ListB collection. Application 1 reloads the object A.
With the solution above, A.ListB remains empty. I had to reload the collection A.ListB explicitly.
Here is a generic way to have all collections reloaded:
var context = ((IObjectContextAdapter)this).ObjectContext;
// detach all added entities
ChangeTracker.Entries().Where(e => e.State == EntityState.Added).ToList().ForEach(e => e.State = EntityState.Detached);
// select entities
var refreshableObjects = ChangeTracker.Entries().Select(e => e.Entity).ToList();
// refresh each refreshable object
foreach (var @object in refreshableObjects)
{
// refresh each collection of the object
context.ObjectStateManager.GetRelationshipManager(@object).GetAllRelatedEnds().Where( r => r.IsLoaded).ToList().ForEach( c => c.Load() );
// refresh the object
context.Refresh(RefreshMode.StoreWins, @object);
}
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