2011-03-07 41 views
38

隨着EF4 CTP5的DbContext刷新實體實例,這個又是什麼用的DbContext

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

相當於我已經試過,但它不會做同樣的事情,更新實例

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

回答

53

您必須使用此:

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

以上不起作用。 Reload()方法無法正確刷新數據庫中的實體。它執行SQL select查詢,但不會爲導航屬性構建代理。見下面的例子(我在SQL Server中使用Northwind數據庫與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) 

我可以得出結論,真正的刷新/ EF實體的重裝可以通過拆離+進行查找:

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

Nakov

+8

從NAA的@迪米塔爾 - 季米特洛夫:'你用你的POCO類的構造函數來創建一個新的產品對象,因此它不會被代理。您應該使用DbSet.Create方法來獲取代理。當您從上下文中分離實體並使用Find方法從數據庫加載它時,實體框架將爲該實體創建一個代理。這就是爲什麼它可以與Detach + Find一起使用。 但是,DbEntityEntry.Reload方法不會刷新實體的關係。' – bummi 2013-11-27 15:22:30

+1

@bummi感謝您發佈該報價。使用DbSet.Create而不是隻是「新」來初始化我的實體,允許我的導航屬性在保存更改並重新加載實體後工作。 – 2014-08-22 14:14:00

+0

非常感謝。這對我有用。當數據在EF之外被修改時,重新加載不起作用。 – user1841243 2014-11-24 10:36:34

0

我發現在具有導航屬性的代理實體上重新加載失敗。

作爲變通,重置當前的值,然後重新加載這樣的:

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