我正在使用实体框架,偶尔我会得到这个错误。

EntityCommandExecutionException
{"There is already an open DataReader associated with this Command which must be closed first."}
   at System.Data.EntityClient.EntityCommandDefinition.ExecuteStoreCommands...

即使我没有做任何手动连接管理。

此错误间歇性地发生。

触发错误的代码(为方便阅读而缩短):

        if (critera.FromDate > x) {
            t= _tEntitites.T.Where(predicate).ToList();
        }
        else {
            t= new List<T>(_tEntitites.TA.Where(historicPredicate).ToList());
        }

使用Dispose模式以便每次都打开新的连接。

using (_tEntitites = new TEntities(GetEntityConnection())) {

    if (critera.FromDate > x) {
        t= _tEntitites.T.Where(predicate).ToList();
    }
    else {
        t= new List<T>(_tEntitites.TA.Where(historicPredicate).ToList());
    }

}

仍然有问题

为什么EF不重用一个连接,如果它已经打开。


当前回答

你得到这个错误,当你试图迭代的集合是一种惰性加载(iquerible)。

foreach (var user in _dbContext.Users)
{    
}

将iquerible集合转换为其他可枚举集合将解决这个问题。 例子

_dbContext.Users.ToList()

注意:. tolist()每次都会创建一个新的集合,如果你在处理大数据,它会导致性能问题。

其他回答

缓解这一问题的2个解决方案:

强制内存缓存保持延迟加载 查询,这样你就可以遍历它,打开一个新的DataReader。 .Include(/你想在查询中加载的附加实体/)this 叫做急装,它允许你(确实)包括 方法执行查询期间的关联对象(实体) DataReader。

这个问题可以简单地通过将数据转换为列表来解决

 var details = _webcontext.products.ToList();


            if (details != null)
            {
                Parallel.ForEach(details, x =>
                {
                    Products obj = new Products();
                    obj.slno = x.slno;
                    obj.ProductName = x.ProductName;
                    obj.Price = Convert.ToInt32(x.Price);
                    li.Add(obj);

                });
                return li;
            }

如果我们试图将部分条件分组到Func<>或扩展方法中,我们将得到这个错误,假设我们有这样的代码:

public static Func<PriceList, bool> IsCurrent()
{
  return p => (p.ValidFrom == null || p.ValidFrom <= DateTime.Now) &&
              (p.ValidTo == null || p.ValidTo >= DateTime.Now);
}

Or

public static IEnumerable<PriceList> IsCurrent(this IEnumerable<PriceList> prices) { .... }

这将抛出异常,如果我们试图在Where()中使用它,我们应该做的是构建一个这样的Predicate:

public static Expression<Func<PriceList, bool>> IsCurrent()
{
    return p => (p.ValidFrom == null || p.ValidFrom <= DateTime.Now) &&
                (p.ValidTo == null || p.ValidTo >= DateTime.Now);
}

更多信息请访问:http://www.albahari.com/nutshell/predicatebuilder.aspx

在我的情况下,我发现在myContext.SaveChangesAsync()调用之前缺少“await”语句。在这些异步调用之前添加await,为我解决了数据读取器的问题。

在我的情况下,这个问题与MARS连接字符串无关,而是与json序列化有关。 在将我的项目从NetCore2升级到3后,我得到了这个错误。

更多信息可以在这里找到