125

How could I refresh my context? I have entities based on views from my Database and when I made an update over one table Entity that has navigation properties to views, the entity is update but the view don't refresh accord the new updates...just want to get again from the Db the data. Thanks!

7 Answers 7

103

The best way to refresh entities in your context is to dispose your context and create a new one.

If you really need to refresh some entity and you are using Code First approach with DbContext class, you can use

    public static void ReloadEntity<TEntity>(
        this DbContext context, 
        TEntity entity)
        where TEntity : class
    {
        context.Entry(entity).Reload();
    }

To reload collection navigation properties, you can use

    public static void ReloadNavigationProperty<TEntity, TElement>(
        this DbContext context, 
        TEntity entity, 
        Expression<Func<TEntity, ICollection<TElement>>> navigationProperty)
        where TEntity : class
        where TElement : class
    {
        context.Entry(entity).Collection<TElement>(navigationProperty).Query();
    }

Reference: https://msdn.microsoft.com/en-us/library/system.data.entity.infrastructure.dbentityentry.reload(v=vs.113).aspx#M:System.Data.Entity.Infrastructure.DbEntityEntry.Reload

Sign up to request clarification or add additional context in comments.

6 Comments

I can't get this to work to reload child navigation properties.
@David you can use context.ReloadNavigationProperty(parent, p => p.Children); if you have class Parent { ICollection<Child> Children; }
In EF Core you can use Query().Load() so for example context.Entry(order).Collection(o => o.NavigationProperty).Query().Load();
I do not understand why this solution is voted so highly. context.Entry(entity).Collection<TElement>(navigationProperty).Query() does not reload the child collection. It only gives you an Iqueryable representing the query used to get the collection. It literally does nothing.
As @Rubenisme said: you need to .Load() at the end.
|
90
yourContext.Entry(yourEntity).Reload();

2 Comments

Thanks for the easy solution. I don't see the necessity in encapsulate this in a extension method like RX_DID_RX did
Note that this does not reload collection navigation properties, only the entity entry itself.
44

If you want to reload specific entities, with the DbContextApi, RX_DID_RX already gave you the answer.

If you want to reload / refresh all the entities you loaded:

If you are using Entity Framework 4.1+ (EF5, or EF 6 probably), DbContext API:

public void RefreshAll()
{
     var entitiesList = ctx.ChangeTracker.Entries().ToList();
     foreach (var entity in entitiesList)
     {
           entity.Reload();
     }
}

If you are using entityFramework 4 (ObjectContext API):

public void RefreshAll()
{
     // Get all objects in statemanager with entityKey
     // (context.Refresh will throw an exception otherwise)
     var refreshableObjects = (from entry in context.ObjectStateManager.GetObjectStateEntries(EntityState.Deleted
                                               | EntityState.Modified
                                               | EntityState.Unchanged)
                                      where entry.EntityKey != null
                                      select entry.Entity);
 
     context.Refresh(RefreshMode.StoreWins, refreshableObjects);
}

Best advice anyway is, try to use a "short lived context" and you'll avoid this kind of problems.

I wrote a couple of articles on the matter:

https://christianarg.wordpress.com/2013/06/13/entityframework-refreshall-loaded-entities-from-database/

2 Comments

To prevent "Collection was modified; enumeration operation may not execute." error I had to change foreach to for var entities = _context.ChangeTracker.Entries().ToArray(); for (int i = 0; i < entities.Length; i++) { entities[i].Reload(); }
@Muflix This was a lifesaver for me. Thanks for positing your fix!
17

Use the Refresh method:

context.Refresh(RefreshMode.StoreWins, yourEntity);

or in alternative dispose your current context and create a new one.

5 Comments

@JMK What exactly doesn't work here? It seems to work fine for me (EF 6.1.1).
@SebastianKrysmanski I commented nearly a year ago, maybe it has been fixed since?
I think that it works only for objectcontext but not dbcontext. A conversation between them is required
@batmaci Which can easily be done with ((IObjectContextAdapter)dbContext).ObjectContext
Which wasn't stated so a little incomplete.
6

context.Reload() was not working for me in MVC 4, EF 5 so I did this.

context.Entry(entity).State = EntityState.Detached;
entity = context.Find(entity.ID);

and its working fine.

Comments

3

EF 6

In my scenario, Entity Framework was not picking up the newly updated data. The reason might be the data was updated outside of its scope. Refreshing data after fetching resolved my issue.

private void RefreshData(DBEntity entity)
{
    if (entity == null) return;

    ((IObjectContextAdapter)DbContext).ObjectContext.RefreshAsync(RefreshMode.StoreWins, entity);
}

private void RefreshData(List<DBEntity> entities)
{
    if (entities == null || entities.Count == 0) return;

    ((IObjectContextAdapter)DbContext).ObjectContext.RefreshAsync(RefreshMode.StoreWins, entities);
}

2 Comments

I'm with EF6. Why is this better than a _context.Entry(entity).Reload();?
As far I can remember, .Reload() is not available in EF6. @CsabaToth
1

Refreshing db context with Reload is not recommended way due to performance loses. It is good enough and the best practice to initialize a new instance of the dbcontext before each operation executed. It also provide you a refreshed up to date context for each operation.

using (YourContext ctx = new YourContext())
{
   //Your operations
}

4 Comments

This is a terrible idea as it effects the ability to write unit tests. If your code goes off and news up a new context, how is that going to work during a unit test?
It would be useful for me and others if you show some samples rather than making criticism.
Its fine for small websites.
Hi @aog, to be helpful, I think the reason for criticism is that it is better to use dependency injection if you can. Also if you need a new DbContext, you can use a DbContextFactory.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.