Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/275.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 实体框架4在保存更改时内存不足_C#_Entity Framework 4 - Fatal编程技术网

C# 实体框架4在保存更改时内存不足

C# 实体框架4在保存更改时内存不足,c#,entity-framework-4,C#,Entity Framework 4,我有一个包含超过50万条记录的表。每个记录包含大约60个字段,但我们只对其中三个字段进行更改 我们在计算和查找的基础上对每个实体进行小的修改 很明显,我不能依次更新每个实体,然后保存更改,因为这将花费太长时间 因此,在整个过程结束时,我在上下文中调用SaveChanges 当我应用SaveChanges 我正在使用DataRepository模式 //Update code DataRepository<ExportOrderSKUData> repoExportOrders = n

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

我们在计算和查找的基础上对每个实体进行小的修改

很明显,我不能依次更新每个实体,然后保存更改,因为这将花费太长时间

因此,在整个过程结束时,我在
上下文中调用
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();
}
//更新代码
DataRepository repoExportOrders=新建DataRepository();
foreach(repoExportOrders.all()中的ExportOrderSkuda grpDCItem)
{
…对enity进行更改。。
}
repoExportOrders.SaveChanges();
//数据存储库snip
公共数据存储库()
{
_上下文=新的实体();
_objectSet=_context.CreateObjectSet();
}
公共列表全部()
{
返回_objectSet.ToList();
}
公共void SaveChanges()
{
_SaveChanges();
}

在这个例子中,我应该寻找什么?

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

首先,我将稍微修改您的代码(自己将其翻译到存储库API):

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


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

您说“显然,我不能依次更新每个实体,然后保存更改,因为这将花费太长的时间。”对一些任意的记录调用
SaveChanges()
是否有效,也许是1024或4096?你看过下面的帖子了吗?@David是的,我试过了,看起来效果不错,但我不确定这是最好的技术解决方案。知道我的意思吗?是的,我感觉到了。然而,内存不足是相当痛苦的——任何缓解都是值得欢迎的。@griegs我认为在您项目的技术范围内,解决方案就在Slauma的答案中。还有其他技术解决方案,如存储过程或basic
SqlCommand
s,它们都不会占用很多客户机资源。这样的解决方案会是你的选择吗?我喜欢这些即使它们不起作用。我仍然出现内存不足错误。然而,我可以从这个答案中看到我在这个项目中可能需要做的其他事情的价值。谢谢您您可能应该使用内存探查器来查找导致问题的确切原因。如果这两个例子都没有帮助,那么可能会有更大的隐藏问题。同意。这可能只是因为我的电脑内存不足,服务器上的问题将不再存在,但现在我无法检查是否存在这种情况。这里有点奇怪。
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();
       }
    }
}
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();
       }
    }
}