【问题标题】:How to clean/Reset ObjectContext in EF 4如何在 EF 4 中清理/重置 ObjectContext
【发布时间】:2011-05-01 18:52:38
【问题描述】:

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

请把递归当成事实。 谢谢

【问题讨论】:

  • 这绝对超出了 EF 的范围。使用另一种技术 - 可能直接使用 SQL。

标签: entity-framework-4


【解决方案1】:

这种操作确实处理得不好,使用实体也不能很好地扩展。我倾向于使用存储过程来进行批处理操作。

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

【讨论】:

  • 谢谢,我熟悉那个解决方案。为了我的目的放慢速度。我已经为我的程序实现了一个“绕过”DAL。谢谢
  • 我也是。期待 Micorosoft 为这类事情提供什么,因为我认为它是 EF 功能中的一个巨大漏洞。甚至删除短期存储DB表中的一堆记录也是比较常见的场景。
【解决方案2】:

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

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

  • 你最终会耗尽内存。

如果可能的话,我总是尝试使用纯 SQL 对数据库进行大批量操作(正如上面的帖子明确指出的那样),但在这种情况下,这不是一个选择。因此,为了解决这个问题,NHibernate 有一个会话上的“清除”方法,它丢弃内存中引用数据库记录的所有对象(新的、添加的、损坏的......) 我试图在实体框架中模仿这种方法如下(使用上面描述的帖子):

    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() 方法是单独使用的,因为它对其他事情很有用。这将进入一个与您的实体类同名的部分类(EF 生成的一个,在本示例中为 MyEntities),因此它在您的实体实例上可用。

我现在每处理 1000 条记录就调用这个 clear 方法,而我过去运行大约 70 分钟的应用程序(只有大约 40 万个实体要处理,甚至数百万)现在在 25 分钟内完成。内存曾经达到峰值 300MB,现在保持在 50MB 左右

【讨论】:

    猜你喜欢
    • 2012-06-05
    • 1970-01-01
    • 2012-05-18
    • 1970-01-01
    • 1970-01-01
    • 2023-03-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多