实体框架从上下文中删除对象,但不从数据库中删除

时间:2012-06-29 00:19:10

标签: c# entity-framework memory-management out-of-memory objectcontext

我正在进行一个批处理过程,它将一个缓慢的遗留数据库(每个记录获取时间为1.4-2ms ......它加起来)的~800,000条记录转储到MySQL中,这可以更快地执行。为了优化这一点,我一直在将所有MySQL记录加载到内存中,这使得使用量大约为200MB。然后,我开始从遗留数据库转储并更新记录。

最初,当这将完成更新记录时,我会调用SaveContext,这将使我的内存从~500MB-800MB跳到1.5GB。很快,我会失去内存异常(运行的虚拟机有2GB的RAM),即使我要给它更多的RAM,1.5-2GB仍然有点过分,这只是一个乐队 - 问题。为了解决这个问题,我开始每10,000条记录调用一次SaveContext,这有点帮助了一些事情,因为我使用委托来从遗留数据库中获取数据并在MySQL中更新它,因此我没有收到太可怕的性能影响。在保存时等待5秒左右,然后在内存中更新已经备份的3000个左右的记录。但是,内存使用量仍在不断增加。

以下是我的潜在问题:

  • 数据以任何顺序来自遗留数据库,因此我无法对更新进行分块并定期发布ObjectContext。
  • 如果我事先没有从MySQL中获取所有数据,而是在记录的更新过程中查找它,那就非常慢了。我事先把它全部抓住,把它扔到一个由主键索引的字典中,当我更新数据时,我从字典中删除了记录。

我想到的一个可能的解决方案是以某种方式释放实体使用的内存,我知道我永远不会再次触摸,因为它们已经更新(比如清除缓存,但只针对特定项目),但我不知道不知道实体框架是否可以实现这一点。

有没有人有任何想法?

2 个答案:

答案 0 :(得分:6)

您可以在上下文中调用Detach方法,将不再需要的对象传递给它: http://msdn.microsoft.com/en-us/library/system.data.objects.objectcontext.detach%28v=vs.90%29.aspx

答案 1 :(得分:2)

我想知道你最好的选择是不是之前建议的其他工具,或者只是放弃使用实体框架。如果您在没有ORM的情况下执行代码,则可以:

  1. 调整SQL语句以提高性能
  2. 轻松控制和更改交易范围,以获得最佳效果。
  3. 您可以批量处理更新,这样您就不会调用服务器来完成多个更新,而不是一次执行一个更新。