如何清理/重置EF 4中的ObjectContext

时间:2011-03-27 11:33:30

标签: entity-framework-4

我有一个包含数百万条记录的层次结构。 我正在对DB进行递归扫描,以便更新一些连接和一些数据。 问题是我得到了一个outofmemory异常,因为整个DB最终被加载到上下文(懒惰)。我不再需要的数据保留在上下文中,没有任何方法可以删除它。 我也不能使用Using(context ...),因为我需要上下文,因为我正在进行递归扫描。

请将递归视为事实。 感谢

2 个答案:

答案 0 :(得分:2)

这种操作实际上处理不好,也不能很好地使用实体。我倾向于使用批处理操作的存储过程。

如果您确实想从上下文中删除/转储对象,我相信this post有一些信息(在底部解决您的问题)。

答案 1 :(得分:2)

刚遇到同样的问题。在使用EF作为ORM工具之前我使用过NHibernate,它有完全相同的问题。只要上下文存活,这些框架就会将对象保留在内存中,这有两个结果:

  • 严重的性能下降:框架会对内存中的对象进行比较(例如,查看对象是否存在)。处理许多记录时,您会注意到性能逐渐下降

  • 你最终会耗尽内存。

如果可能的话,我总是尝试使用纯SQL对数据库进行大批量操作(如上面的帖子明确说明的那样),但在这种情况下,这不是一个选项。所以为了解决这个问题,NHibernate在会话中使用了一个'Clear'方法,它抛弃了内存中引用数据库记录的所有对象(新的,添加的,腐败的......) 我试图在实体框架中模仿这个方法如下(使用上面描述的帖子):

    public partial class MyEntities
    {

        public IEnumerable<ObjectStateEntry> GetAllObjectStateEntries()
        {
            return ObjectStateManager.GetObjectStateEntries(EntityState.Added |
                                                        EntityState.Deleted |
                                                        EntityState.Modified |
                                                        EntityState.Unchanged);
        }

        public void ClearEntities()
        {
            foreach (var objectStateEntry in GetAllObjectStateEntries())
            {
                Detach(objectStateEntry.Entity);
            }
        }
    }

GetAllObjectStateEntries()方法是单独使用的,因为它对其他东西很有用。这将进入与您的Entities类同名的部分类(EF中生成的一个,本例中为MyEntities),因此它可以在您的实体实例上使用。

我现在每隔1000个记录调用这个清晰的方法,我的应用程序过去运行大约70分钟(只有大约400,000个实体要处理,甚至数百万个)现在在25分钟内完成。内存常常达到300MB,现在大约为50MB