gpt4 book ai didi

c# - Entity Framework 4 SaveChanges 内存不足

转载 作者:行者123 更新时间:2023-11-30 22:18:45 25 4
gpt4 key购买 nike

我有一个包含超过 50 万条记录的表。每条记录包含大约 60 个字段,但我们只更改其中三个。

我们根据计算和查找对每个实体进行小的修改。

很明显,我无法依次更新每个实体,然后再SaveChanges,因为那样会花费太长时间。

所以在整个过程结束时,我在 Context 上调用了 SaveChanges

当我应用 SaveChanges 时,这会导致内存不足错误

我正在使用 DataRepository 模式。

//Update code
DataRepository<ExportOrderSKUData> repoExportOrders = new DataRepository<ExportOrderSKUData>();
foreach (ExportOrderSKUData grpDCItem in repoExportOrders.all())
{
..make changes to enity..
}
repoExportOrders.SaveChanges();



//Data repository snip
public DataRepository()
{
_context = new tomEntities();
_objectSet = _context.CreateObjectSet<T>();
}
public List<T> All()
{
return _objectSet.ToList<T>();
}
public void SaveChanges()
{
_context.SaveChanges();
}

在这种情况下我应该寻找什么?

最佳答案

在一个事务中通过 EF 更改 50 万条记录不应该是用例。小批量做是更好的技术方案。通过一些存储过程在数据库端执行此操作可能是更好的解决方案。

我会先稍微修改一下您的代码(自己将其翻译成您的存储库 API):

using (var readContext = new YourContext()) {
var set = readContext.CreateObjectSet<ExportOrderSKUData>();

foreach (var item in set.ToList()) {
readContext.Detach(item);
using (var updateContext = new YourContext()) {
updateContext.Attach(item);
// make your changes
updateContext.SaveChanges();
}
}
}

此代码使用单独的上下文来保存项目 = 每次保存都在其自己的事务中。不要害怕那个。即使您尝试在 SaveChanges 的一次调用中保存更多记录,EF 也会对每条更新的记录使用单独的数据库往返。唯一的区别是,如果您想在同一个事务中进行多个更新(但是在单个事务中进行 50 万次更新无论如何都会导致问题)。

另一种选择可能是:

using (var readContext = new YourContext()) {
var set = readContext.CreateObjectSet<ExportOrderSKUData>();
set.MergeOption = MergeOption.NoTracking;

foreach (var item in set) {
using (var updateContext = new YourContext()) {
updateContext.Attach(item);
// make your changes
updateContext.SaveChanges();
}
}
}

理论上这可以消耗更少的内存,因为您不需要在执行 foreach 之前加载所有实体。第一个示例可能需要在枚举之前加载所有实体(通过调用 ToList)以避免在调用 Detach(在枚举期间修改集合)时出现异常 - 但我不确定如果那真的发生了。

修改这些示例以使用一些批处理应该很容易。

关于c# - Entity Framework 4 SaveChanges 内存不足,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15941471/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com