使用Entity Framework刷新数据

9

我正在尝试使用Entity Framework查询数据库,并且我有以下代码可用于获取一些数据。

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

这段代码可以正常运行并返回正确的数据。但是,如果我运行此代码,然后转到数据库并更新记录以更改此代码应返回的数据,然后在不关闭应用程序的情况下重新运行此代码,则会获取原始数据。 我很确定它曾经可以正常工作,但现在它没有刷新数据。

2个回答

17
不,它从来没有起作用。这是实体框架(和许多ORM工具)的基本行为,称为标识映射(在此处有解释)。
如果在同一个上下文中运行查询,您将不会更新实体。它只会添加在运行这两个查询之间在数据库中创建的新实体。如果您想强制EF重新加载实体,您必须像这样做:
ObjectQuery query = MyEntities.Students;
query.MergeOption = MergeOption.OverwriteChanges;
var students = query.Where(s => s.Age > 20).ToList();

如果你只是在查询,应该使用 MergeOption.NoTracking 吗?这将强制查询命中数据库。 - Nix
查询将无论如何命中数据库。我不确定在使用NoTracking时,如果您已经在“缓存”中拥有实体,会发生什么,因为当使用延迟加载EF时,它仍然会保留它们。 - Ladislav Mrnka
这似乎做到了我想要的。使用Refresh()方法也可以,但我认为使用ObjectQuery是更清晰的解决方案。将其标记为答案。然而,Nix提出了关于使用EF的最佳实践的好观点,需要更多地了解,所以我需要进一步研究。 - chiefanov

6
你会遇到问题,因为EF缓存数据,如果在幕后数据发生更改,而你不处理/重新打开你的上下文,你就会遇到问题。
一般的经验法则是尽可能地保持上下文的生命周期短,以避免像你刚提到的问题。
请不要忽略我上面说的话,但如果你想从数据库强制刷新,你可以使用Refresh()方法。

请注意,对于较大的数据集,刷新操作会执行许多查询,除了可能会或可能不会执行的实际查询之外,而query.MergeOption只是强制从数据库读取查询。 - yoel halb

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接