mare
mare

Reputation: 13083

Refresh entity instance with DbContext

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();
    }

?

Upvotes: 41

Views: 39984

Answers (3)

Matstar
Matstar

Reputation: 410

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();

Upvotes: -1

Svetlin Nakov
Svetlin Nakov

Reputation: 1669

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

Upvotes: 27

Ladislav Mrnka
Ladislav Mrnka

Reputation: 364409

You must use this:

public void Refresh(Document instance)
{
  _ctx.Entry<Document>(instance).Reload();
}

Upvotes: 58

Related Questions