2011-05-25 134 views
9

我想使用实体框架来查询数据库,我有以下代码,我用来获取一些数据。刷新数据使用实体框架

var students= MyEntities.Students.Where(s => s.Age > 20).ToList(); 

此代码正常工作并返回正确的数据。但是,如果我运行此代码,然后转到数据库并更新记录以更改此代码应返回的数据,然后重新运行此代码而不关闭应用程序,我将获取原始数据。 我很确定它用于正常工作,但现在这不刷新数据。

回答

16

不,它从来没有工作。这是实体框架(和许多ORM工具)称为标识映射(explanation here)的基本行为。

如果您在相同的上下文中运行查询,则不会更新您的实体。它只会追加运行这两个查询之间在数据库中创建的新实体。如果要强制EF重新加载实体必须做这样的事情:

ObjectQuery query = MyEntities.Students; 
query.MergeOption = MergeOption.OverwriteChanges; 
var students = query.Where(s => s.Age > 20).ToList(); 
+0

如果你只是查询你应该使用'MergeOption.NoTracking'?这将强制查询命中数据库。 – Nix 2011-05-25 15:32:20

+0

无论如何查询都会碰到DB。我不确定当你使用'NoTracking'时会发生什么,并且你已经在“缓存”中有实体,因为当使用延迟加载时EF仍然保留它们。 – 2011-05-25 15:34:33

+0

这似乎是做我想做的事情。使用Refresh()方法也可以,但我认为使用ObjectQuery是一个更干净的解决方案。标记为答案。然而,Nix在使用EF时提供了一个很好的关于最佳实践的观点,这对了解更多信息是很好的,所以我需要更多地了解这一点。 – chiefanov 2011-05-25 16:38:41

6

由于EF会缓存数据,所以如果数据在幕后更改,并且您不处理/重新打开上下文,则会遇到问题。

一般的经验法则是保持上下文的生命周期尽可能短,以避免像刚刚提到的问题。

请不要忽视我上面所说的内容,但是如果您想强制从数据库刷新,可以使用Refresh()方法。

+0

注意,刷新正在做许多查询,以更大的数据集,除了可能会或可能不会被执行的实际查询,而query.MergeOption是只是迫使查询从数据库中读取 – 2013-12-05 00:05:10