【问题标题】:New transaction is not allowed because there are other threads running in the session. Entity Framework不允许新事务,因为会话中正在运行其他线程。实体框架
【发布时间】:2017-03-27 17:07:29
【问题描述】:

我有这个简单的代码:

foreach(var myvar in _sdb.Vars)
{
    myvar.Area= AreaCheck(myvar);

    _sdb.Entry(myvar).State = System.Data.Entity.EntityState.Modified;
    _sdb.SaveChanges();
}

当我运行这段代码时,我得到了这个异常:

不允许新事务,因为还有其他线程 在会话中运行。

我用谷歌搜索了这个问题,其中一个答案告诉我要更改这一行:

foreach(var myvar in _sdb.Vars)

到这一行:

foreach(var myvar in _sdb.Vars.ToList())

但是当我这样做时,代码根本不起作用。我怎样才能使这项工作?谢谢。

【问题讨论】:

  • var myvar in _sdb.Vars 将抛出错误,因为 sdb.VarsIQueryable 并且您正在尝试修改它的状态。 foreach(var myvar in _sdb.Vars.ToList()) 应该可以工作,但取决于您在 AreaCheck(myvar) 方法中所做的事情。请同时添加该代码。此外,将_sdb.SaveChanges(); 移到foreach 循环之外以避免多次数据库命中
  • “但是当我这样做时,代码根本不起作用” - 怎么不起作用?

标签: c# entity-framework linq


【解决方案1】:

如下迭代后保存

using (var _sdb = new MyContext())
{
    foreach (var myvar in _sdb.Vars)
    {
        // Change myvar
    }
     //save at the end
    _sdb.SaveChanges();
}

【讨论】:

  • 数据库中有300000条记录。这还能用吗?
  • 这适用于小数据集,如果这是大数据集,那么你最好将它们作为块获取。检查这个 asnwer stackoverflow.com/a/3902790/2558060
  • 或者干脆不使用 ORM 来做那种事情。只需使用存储过程之类的方法告诉您的数据库服务器。
  • @CodeNotFound 是的,这将是一个更好的解决方案,但我们不知道 OP 的确切要求。如果 OP 在更新时更多地依赖 ORM 数据并且在这种情况下或使用时间线无法将所有内容移动到数据库端,那么我们必须尝试其中一种
猜你喜欢
  • 2017-06-26
  • 2012-04-23
  • 2016-07-07
  • 1970-01-01
  • 1970-01-01
  • 2012-09-07
  • 2021-08-20
相关资源
最近更新 更多