Entity framework 4 如何在EF 4中清理/重置ObjectContext
我有一个拥有数百万条记录的层次结构。 我正在对数据库进行递归扫描,以更新一些连接和一些数据。 问题是,我得到了一个outofmemory异常,因为整个数据库最终被加载到上下文(lazy)。我不再需要的数据会保留在上下文中,而不会以任何方式删除它。 我也不能使用Using(context…),因为我需要上下文处于活动状态,因为我正在进行递归扫描 请把递归当作事实。Entity framework 4 如何在EF 4中清理/重置ObjectContext,entity-framework-4,Entity Framework 4,我有一个拥有数百万条记录的层次结构。 我正在对数据库进行递归扫描,以更新一些连接和一些数据。 问题是,我得到了一个outofmemory异常,因为整个数据库最终被加载到上下文(lazy)。我不再需要的数据会保留在上下文中,而不会以任何方式删除它。 我也不能使用Using(context…),因为我需要上下文处于活动状态,因为我正在进行递归扫描 请把递归当作事实。 感谢这种操作实际上处理得不好,使用实体也不能很好地扩展。对于批处理操作,我倾向于使用存储过程 如果您确实想从上下文中删除/转储对象,我
感谢这种操作实际上处理得不好,使用实体也不能很好地扩展。对于批处理操作,我倾向于使用存储过程
如果您确实想从上下文中删除/转储对象,我相信您有一些信息(底部的问题解决方案)。这种操作实际上处理得不好,使用实体也不能很好地扩展。对于批处理操作,我倾向于使用存储过程
如果您确实想从上下文中删除/转储对象,我相信有一些信息(底部的问题解决方案)。刚刚遇到了相同的问题。在使用EF作为ORM工具之前,我已经使用过NHibernate,它也有同样的问题。只要上下文处于活动状态,这些框架就将对象保存在内存中,这有两个后果:
- 严重性能下降:框架在内存中的对象之间进行比较(例如,查看对象是否存在)。在处理许多记录时,您会注意到性能逐渐下降
- 您最终将耗尽内存
公共部分类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,它也有同样的问题。只要上下文处于活动状态,这些框架就将对象保存在内存中,这有两个后果:
- 严重性能下降:框架在内存中的对象之间进行比较(例如,查看对象是否存在)。在处理许多记录时,您会注意到性能逐渐下降
- 您最终将耗尽内存
公共部分类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);
}
}
}