41

With EF4 CTP5 DbContext, what is the equivalent of this

    public void Refresh(Document instance)
    {
        _ctx.Refresh(RefreshMode.StoreWins, instance);
    }

I've tried this but it doesn't do the same thing, updating the instance

    public void Refresh(Document instance)
    {
        _ctx.ChangeTracker.DetectChanges();
    }

?

3 Answers 3

58

You must use this:

public void Refresh(Document instance)
{
  _ctx.Entry<Document>(instance).Reload();
}
Sign up to request clarification or add additional context in comments.

Comments

27

The above doesn't work. Reload() method does not correctly refresh the entity from the database. It performs SQL select query but does not build proxies for the navigational properties. See the example below (I use the Northwind database in SQL Server with EF 5.1):

NorthwindEntities northwindEntities = new NorthwindEntities();
Product newProduct = new Product
{
    ProductName = "new product",
    Discontinued = false,
    CategoryID = 3
};
northwindEntities.Products.Add(newProduct);
northwindEntities.SaveChanges();

// Now the product is stored in the database. Let's print its category

Console.WriteLine(newProduct.Category); // prints "null" -> navigational property not loaded

// Find the product by primary key --> returns the same object (unmodified)
// Still prints "null" (due to caching and identity resolution)
var productByPK = northwindEntities.Products.Find(newProduct.ProductID);
Console.WriteLine(productByPK.Category); // null (due to caching)

// Reloading the entity from the database doesn't help!
northwindEntities.Entry<Product>(newProduct).Reload();
Console.WriteLine(newProduct.Category); // null (reload doesn't help)

// Detach the object from the context
((IObjectContextAdapter)northwindEntities).ObjectContext.Detach(newProduct);

// Now find the product by primary key (detached entities are not cached)
var detachedProductByPK = northwindEntities.Products.Find(newProduct.ProductID);
Console.WriteLine(detachedProductByPK.Category); // works (no caching)

I may conclude that real refresh / reload of EF entity can be done by Detach + Find:

((IObjectContextAdapter)context).ObjectContext.Detach(entity);
entity = context.<SomeEntitySet>.Find(entity.PrimaryKey);

Nakov

5 Comments

From a NAA of @Dimitar-Dimitrov: You use the constructor of your POCO class to create a new Product object and thus it will not be proxy. You should use the DbSet.Create method in order to get proxy. When you detach the entity from the context and load it from the database with the Find method, Entity Framework will create a proxy for the entity. That's why it works with Detach+Find. However, DbEntityEntry.Reload method will not refresh the relationships of the entity.
@bummi Thanks for posting that quote. Using DbSet.Create instead of just "new <Entity>" to initialize my entity allowed my navigation properties to work after saving changes and reloading the entity.
Thank you very much. This works for me. Reload does not work for either when data has been modified outside of EF.
strange behaviour: after deleting and re-adding a child entity to a parent... my refreshed parent-entity has now 2 children instead of 1... The deleted child-entity is still there for some reason.
I tried the Create, Add, Save and Reload method and my variable still did not have my new entity's database Id. How the heck is this so difficult?
-1

I found that the reload fails on proxy entities that have navigation properties.

As a work around, reset the current values and then reload like this:

var entry =_ctx.Entry<Document>(instance);
entry.CurrentValues.SetValues(entry.OriginalValues); 
entry.Reload();

1 Comment

Does not work. Relationships are not reseted to original values.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.