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

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不重用一个连接,如果它已经打开。


当前回答

通过向构造函数中添加选项,我轻松地(实用地)解决了这个问题。因此,我只在需要时使用它。

public class Something : DbContext
{
    public Something(bool MultipleActiveResultSets = false)
    {
        this.Database
            .Connection
            .ConnectionString = Shared.ConnectionString /* your connection string */
                              + (MultipleActiveResultSets ? ";MultipleActiveResultSets=true;" : "");
    }
...

其他回答

It is not about closing connection. EF manages connection correctly. My understanding of this problem is that there are multiple data retrieval commands executed on single connection (or single command with multiple selects) while next DataReader is executed before first one has completed the reading. The only way to avoid the exception is to allow multiple nested DataReaders = turn on MultipleActiveResultSets. Another scenario when this always happens is when you iterate through result of the query (IQueryable) and you will trigger lazy loading for loaded entity inside the iteration.

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

更多信息可以在这里找到

我最初决定在我的API类中使用一个静态字段来引用MyDataContext对象的实例(其中MyDataContext是一个EF5 Context对象),但这似乎是造成问题的原因。我在每个API方法中都添加了如下代码,从而解决了这个问题。

using(MyDBContext db = new MyDBContext())
{
    //Do some linq queries
}

正如其他人所说,EF数据上下文对象不是线程安全的。因此,在适当的条件下,将它们放置在静态对象中最终会导致“数据读取器”错误。

我最初的假设是只创建对象的一个实例会更有效,并提供更好的内存管理。从我研究这个问题所收集到的资料来看,情况并非如此。事实上,将对API的每个调用视为一个独立的线程安全事件似乎更有效。确保当对象超出作用域时,所有资源都被适当释放。

这是有意义的,特别是如果你把你的API带到下一个自然的进程,即将它公开为WebService或REST API。

信息披露

操作系统:Windows Server 2012 .NET:安装4.5,项目使用4.0 数据来源:MySQL 应用程序框架:MVC3 身份验证:形式

我发现我有同样的错误,它发生在我使用Func<TEntity时,bool>而不是表达式<Func<TEntity, bool>>作为谓词。

一旦我改变了所有的Func的表达式的异常停止抛出。

我相信entityframework在Expression中做了一些聪明的事情,这是它在Func中做不到的

我注意到,当我发送一个iquerible到视图并在双foreach中使用它时,这个错误发生了,其中内部foreach也需要使用连接。简单的例子(ViewBag。parent可以是iqueryable或者DbSet):

foreach (var parent in ViewBag.parents)
{
    foreach (var child in parent.childs)
    {

    }
}

简单的解决方案是在使用集合之前对其使用. tolist()。还要注意,MARS不能与MySQL一起工作。