Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

?

like image 637
mare Avatar asked Mar 07 '11 15:03

mare


People also ask

How do you refresh entity?

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

How does DbContext change state of entity?

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.

Should you use using with DbContext?

EF and EF Core DbContext types implement IDisposable . As such, best practice programming suggests that you should wrap them in a using() block (or new C# 8 using statement). Unfortunately, doing this, at least in web apps, is generally a bad idea.


2 Answers

You must use this:

public void Refresh(Document instance) {   _ctx.Entry<Document>(instance).Reload(); } 
like image 51
Ladislav Mrnka Avatar answered Oct 06 '22 14:10

Ladislav Mrnka


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

like image 39
Svetlin Nakov Avatar answered Oct 06 '22 14:10

Svetlin Nakov