2011-03-07 67 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();