Entity framework 4 如何在EF 4中清理/重置ObjectContext

Entity framework 4 如何在EF 4中清理/重置ObjectContext,entity-framework-4,Entity Framework 4,我有一个拥有数百万条记录的层次结构。 我正在对数据库进行递归扫描,以更新一些连接和一些数据。 问题是,我得到了一个outofmemory异常,因为整个数据库最终被加载到上下文(lazy)。我不再需要的数据会保留在上下文中,而不会以任何方式删除它。 我也不能使用Using(context…),因为我需要上下文处于活动状态,因为我正在进行递归扫描 请把递归当作事实。 感谢这种操作实际上处理得不好,使用实体也不能很好地扩展。对于批处理操作,我倾向于使用存储过程 如果您确实想从上下文中删除/转储对象,我

我有一个拥有数百万条记录的层次结构。 我正在对数据库进行递归扫描,以更新一些连接和一些数据。 问题是,我得到了一个outofmemory异常,因为整个数据库最终被加载到上下文(lazy)。我不再需要的数据会保留在上下文中,而不会以任何方式删除它。 我也不能使用Using(context…),因为我需要上下文处于活动状态,因为我正在进行递归扫描

请把递归当作事实。
感谢

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


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

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


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

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

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

  • 您最终将耗尽内存

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

公共部分类MyEntities
{
公共IEnumerable GetAllObjectStateEntries()
{
返回ObjectStateManager.GetObjectStateEntries(EntityState.Added|
EntityState。已删除|
EntityState.Modified|
实体状态。未更改);
}
公共实体()
{
foreach(GetAllObjectStateEntries()中的var objectStateEntry)
{
分离(objectStateEntry.Entity);
}
}
}
GetAllObjectStateEntries()方法是单独使用的,因为它对其他事情很有用。这进入了一个与Entities类同名的分部类(本例中是EF生成的MyEntities),因此它在Entities实例上可用


我现在每处理1000条记录调用一次clear方法,我的应用程序过去运行大约70分钟(只处理大约40万个实体,甚至数百万个实体),现在只需25分钟即可完成。以前的内存峰值为300MB,现在保持在50MB左右,但也遇到了同样的问题。在使用EF作为ORM工具之前,我已经使用过NHibernate,它也有同样的问题。只要上下文处于活动状态,这些框架就将对象保存在内存中,这有两个后果:

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

  • 您最终将耗尽内存

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

公共部分类MyEntities
{
公共IEnumerable GetAllObjectStateEntries()
{
返回ObjectStateManager.GetObjectStateEntries(EntityState.Added|
EntityState。已删除|
EntityState.Modified|
实体状态。未更改);
}
公共实体()
{
foreach(GetAllObjectStateEntries()中的var objectStateEntry)
{
分离(objectStateEntry.Entity);
}
}
}
GetAllObjectStateEntries()方法是单独使用的,因为它对其他事情很有用。这进入了一个与Entities类同名的分部类(本例中是EF生成的MyEntities),因此它在Entities实例上可用


我现在每处理1000条记录调用一次clear方法,我的应用程序过去运行大约70分钟(只处理大约40万个实体,甚至数百万个实体),现在只需25分钟即可完成。内存过去峰值为300MB,现在保持在50MB左右

这绝对超出了EF的范围。使用另一种技术-可能是直接使用SQL。这绝对超出了EF的范围。使用另一种技术-可能是直接使用SQL。谢谢,我熟悉该解决方案。为了我的目的放慢脚步。我已经为我的程序实现了一个“旁路”DAL。谢谢。期待Micorosoft为这类事情提供的帮助,因为我认为这是EF功能中的一个巨大漏洞。甚至删除短期存储数据库表中的一组记录也是一种比较常见的情况
    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);
            }
        }
    }