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