Ya hay un DataReader abierto asociado con este Comando que debe cerrarse primero


Tengo esta consulta y obtengo el error en esta función:

var accounts = from account in context.Accounts
               from guranteer in account.Gurantors
               select new AccountsReport
               {
                   CreditRegistryId = account.CreditRegistryId,
                   AccountNumber = account.AccountNo,
                   DateOpened = account.DateOpened,
               };

 return accounts.AsEnumerable()
                .Select((account, index) => new AccountsReport()
                    {
                        RecordNumber = FormattedRowNumber(account, index + 1),
                        CreditRegistryId = account.CreditRegistryId,
                        DateLastUpdated = DateLastUpdated(account.CreditRegistryId, account.AccountNumber),
                        AccountNumber = FormattedAccountNumber(account.AccountType, account.AccountNumber)
                    })
                .OrderBy(c=>c.FormattedRecordNumber)
                .ThenByDescending(c => c.StateChangeDate);


public DateTime DateLastUpdated(long creditorRegistryId, string accountNo)
{
    return (from h in context.AccountHistory
            where h.CreditorRegistryId == creditorRegistryId && h.AccountNo == accountNo
            select h.LastUpdated).Max();
}

El error es:

Ya hay un DataReader abierto asociado con este Comando que debe cerrarse primero.

Actualización:

Stack trace añadido:

InvalidOperationException: There is already an open DataReader associated with this Command which must be closed first.]
   System.Data.SqlClient.SqlInternalConnectionTds.ValidateConnectionForExecute(SqlCommand command) +5008639
   System.Data.SqlClient.SqlConnection.ValidateConnectionForExecute(String method, SqlCommand command) +23
   System.Data.SqlClient.SqlCommand.ValidateCommand(String method, Boolean async) +144
   System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, DbAsyncResult result) +87
   System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method) +32
   System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior behavior, String method) +141
   System.Data.SqlClient.SqlCommand.ExecuteDbDataReader(CommandBehavior behavior) +12
   System.Data.Common.DbCommand.ExecuteReader(CommandBehavior behavior) +10
   System.Data.EntityClient.EntityCommandDefinition.ExecuteStoreCommands(EntityCommand entityCommand, CommandBehavior behavior) +443

[EntityCommandExecutionException: An error occurred while executing the command definition. See the inner exception for details.]
   System.Data.EntityClient.EntityCommandDefinition.ExecuteStoreCommands(EntityCommand entityCommand, CommandBehavior behavior) +479
   System.Data.Objects.Internal.ObjectQueryExecutionPlan.Execute(ObjectContext context, ObjectParameterCollection parameterValues) +683
   System.Data.Objects.ObjectQuery`1.GetResults(Nullable`1 forMergeOption) +119
   System.Data.Objects.ObjectQuery`1.System.Collections.Generic.IEnumerable<T>.GetEnumerator() +38
   System.Linq.Enumerable.Single(IEnumerable`1 source) +114
   System.Data.Objects.ELinq.ObjectQueryProvider.<GetElementFunction>b__3(IEnumerable`1 sequence) +4
   System.Data.Objects.ELinq.ObjectQueryProvider.ExecuteSingle(IEnumerable`1 query, Expression queryRoot) +29
   System.Data.Objects.ELinq.ObjectQueryProvider.System.Linq.IQueryProvider.Execute(Expression expression) +91
   System.Data.Entity.Internal.Linq.DbQueryProvider.Execute(Expression expression) +69
   System.Linq.Queryable.Max(IQueryable`1 source) +216
   CreditRegistry.Repositories.CreditRegistryRepository.DateLastUpdated(Int64 creditorRegistryId, String accountNo) in D:\Freelance Work\SuperExpert\CreditRegistry\CreditRegistry\Repositories\CreditRegistryRepository.cs:1497
   CreditRegistry.Repositories.CreditRegistryRepository.<AccountDetails>b__88(AccountsReport account, Int32 index) in D:\Freelance Work\SuperExpert\CreditRegistry\CreditRegistry\Repositories\CreditRegistryRepository.cs:1250
   System.Linq.<SelectIterator>d__7`2.MoveNext() +198
   System.Linq.Buffer`1..ctor(IEnumerable`1 source) +217
   System.Linq.<GetEnumerator>d__0.MoveNext() +96
Author: abatishchev, 2011-05-19

16 answers

Esto puede suceder si ejecuta una consulta mientras itera sobre los resultados de otra consulta. No está claro en su ejemplo donde esto sucede porque el ejemplo no está completo.

Una cosa que puede causar esto es la carga lenta activada cuando se itera sobre los resultados de alguna consulta.

Esto se puede resolver fácilmente permitiendo MARS en su cadena de conexión. Agregue MultipleActiveResultSets=true a la parte del proveedor de su cadena de conexión (donde la fuente de datos, el Catálogo inicial, etc. ser indicado).

 1057
Author: Ladislav Mrnka,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-09-19 00:36:42

Puede usar el método ToList() antes de la instrucción return.

var accounts =
from account in context.Accounts
from guranteer in account.Gurantors

 select new AccountsReport
{
    CreditRegistryId = account.CreditRegistryId,
    AccountNumber = account.AccountNo,
    DateOpened = account.DateOpened,
};

 return accounts.AsEnumerable()
               .Select((account, index) => new AccountsReport()
                       {
                           RecordNumber = FormattedRowNumber(account, index + 1),
                           CreditRegistryId = account.CreditRegistryId,
                              DateLastUpdated = DateLastUpdated(account.CreditRegistryId, account.AccountNumber),
                           AccountNumber = FormattedAccountNumber(account.AccountType, account.AccountNumber)}).OrderBy(c=>c.FormattedRecordNumber).ThenByDescending(c => c.StateChangeDate).ToList();


 public DateTime DateLastUpdated(long creditorRegistryId, string accountNo)
    {
        var dateReported = (from h in context.AccountHistory
                            where h.CreditorRegistryId == creditorRegistryId && h.AccountNo == accountNo
                            select h.LastUpdated).Max();
        return dateReported;
    }
 176
Author: kazem,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-07-18 13:21:57

Aquí hay una cadena de conexión que funciona para alguien que necesita referencia.

  <connectionStrings>
    <add name="IdentityConnection" connectionString="Data Source=(LocalDb)\v11.0;AttachDbFilename=|DataDirectory|\IdentityDb.mdf;Integrated Security=True;MultipleActiveResultSets=true;" providerName="System.Data.SqlClient" />
  </connectionStrings>
 15
Author: Yang Zhang,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-07-17 04:15:44

En mi caso, usar Include() solucionó este error y dependiendo de la situación puede ser mucho más eficiente que emitir múltiples consultas cuando todas se pueden consultar a la vez con una combinación.

IEnumerable<User> users = db.Users.Include("Projects.Tasks.Messages");

foreach (User user in users)
{
    Console.WriteLine(user.Name);
    foreach (Project project in user.Projects)
    {
        Console.WriteLine("\t"+project.Name);
        foreach (Task task in project.Tasks)
        {
            Console.WriteLine("\t\t" + task.Subject);
            foreach (Message message in task.Messages)
            {
                Console.WriteLine("\t\t\t" + message.Text);
            }
        }
    }
}
 13
Author: Despertar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-04-15 07:05:08

Use la sintaxis .ToList() para convertir el objeto leído de la base de datos a la lista para evitar que se vuelva a leer.Espero que esto funcione. Gracias.

 13
Author: Icemark Muturi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-04-18 08:23:04

No sé si esta es una respuesta duplicada o no. Si lo es, lo siento. Solo quiero que los necesitados sepan cómo resolví mi problema usando ToList ().

En mi caso tengo la misma excepción para la siguiente consulta.

int id = adjustmentContext.InformationRequestOrderLinks.Where(item => item.OrderNumber == irOrderLinkVO.OrderNumber && item.InformationRequestId == irOrderLinkVO.InformationRequestId).Max(item => item.Id);

Resolví como a continuación

List<Entities.InformationRequestOrderLink> links = adjustmentContext.InformationRequestOrderLinks
.Where(item => item.OrderNumber == irOrderLinkVO.OrderNumber && item.InformationRequestId == irOrderLinkVO.InformationRequestId).ToList();

int id = 0;

if (links.Any())
{
  id = links.Max(x => x.Id);
 }
if (id == 0)
{
//do something here
}
 6
Author: Ziggler,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-08-25 18:55:37

Parece que está llamando a DateLastUpdated desde una consulta activa utilizando el mismo contexto EF y DateLastUpdate emite un comando al propio almacén de datos. Entity Framework solo admite un comando activo por contexto a la vez.

Puede refactorizar sus dos consultas anteriores en una como esta:

return accounts.AsEnumerable()
        .Select((account, index) => new AccountsReport()
        {
          RecordNumber = FormattedRowNumber(account, index + 1),
          CreditRegistryId = account.CreditRegistryId,
          DateLastUpdated = (
                                                from h in context.AccountHistory 
                                                where h.CreditorRegistryId == creditorRegistryId 
                              && h.AccountNo == accountNo 
                                                select h.LastUpdated).Max(),
          AccountNumber = FormattedAccountNumber(account.AccountType, account.AccountNumber)
        })
        .OrderBy(c=>c.FormattedRecordNumber)
        .ThenByDescending(c => c.StateChangeDate);

También noté que estás llamando a funciones como FormattedAccountNumber y FormattedRecordNumber en las consultas. A menos que estos son procs almacenados o funciones que has importados de su base de datos en el modelo de datos de entidad y asignados correctamente, estos también arrojarán excepciones ya que EF no sabrá cómo traducir esas funciones en declaraciones que puede enviar al almacén de datos.

También tenga en cuenta que llamar a AsEnumerable no obliga a ejecutar la consulta. Hasta que la ejecución de la consulta se aplace hasta que se enumere. Puede forzar la enumeración con ToList o toArray si así lo desea.

 4
Author: James Alexander,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-05-19 18:22:51

Además de la respuesta de Ladislav Mrnka :

Si está publicando y sobrescribiendo el contenedor en la pestaña Settings, puede establecer MultipleActiveResultSet en True. Puede encontrar esta opción haciendo clic en Avanzado... y va a estar bajo Avanzado grupo.

 2
Author: Alexander Troshchenko,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-10-17 16:45:38

Tuve el mismo error, cuando traté de actualizar algunos registros dentro de read loop. He probado la respuesta más votada MultipleActiveResultSets=true y encontré, que es solo una solución para obtener el siguiente error

No se permite una nueva transacción porque hay otros subprocesos en ejecución en la sesión

El mejor enfoque, que funcionará para grandes ResultSets es usar trozos y abrir contexto separado para cada trozo como se describe en  SQLException de Entity Framework - Nueva transacción es no se permite porque hay otros subprocesos en ejecución en la sesión

 1
Author: Michael Freidgeim,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 11:55:01

Resolví este problema cambiando await _accountSessionDataModel.SaveChangesAsync(); a _ Cuenta con un modelo.SaveChanges(); en mi clase de Repositorio.

 public async Task<Session> CreateSession()
    {
        var session = new Session();

        _accountSessionDataModel.Sessions.Add(session);
        await _accountSessionDataModel.SaveChangesAsync();
     }

Lo cambió a:

 public Session CreateSession()
    {
        var session = new Session();

        _accountSessionDataModel.Sessions.Add(session);
        _accountSessionDataModel.SaveChanges();
     }

El problema fue que actualizé las Sesiones en el frontend después de crear una sesión (en código), pero debido a que SaveChangesAsync ocurre asincrónicamente, la búsqueda de las sesiones causó este error porque aparentemente la operación SaveChangesAsync aún no estaba lista.

 1
Author: woutercx,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-07-21 14:01:06

Para aquellos que encuentran esto a través de Google;
Estaba recibiendo este error porque, como sugiere el error, no pude cerrar un SqlDataReader antes de crear otro en el mismo SqlCommand, asumiendo erróneamente que sería basura recolectada al salir del método en el que fue creado.

Resolví el problema llamando a sqlDataReader.Close(); antes de crear el segundo lector.

 1
Author: timelmer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-07-21 18:01:22

En mi caso, había abierto una consulta desde el contexto de datos, como

    Dim stores = DataContext.Stores _
        .Where(Function(d) filter.Contains(d.code)) _

... y luego preguntó lo mismo...

    Dim stores = DataContext.Stores _
        .Where(Function(d) filter.Contains(d.code)).ToList

Agregar el .ToList al primero resolvió mi problema. Creo que tiene sentido envolver esto en una propiedad como:

Public ReadOnly Property Stores As List(Of Store)
    Get
        If _stores Is Nothing Then
            _stores = DataContext.Stores _
                .Where(Function(d) Filters.Contains(d.code)).ToList
        End If
        Return _stores
    End Get
End Property

Donde _stores es una variable privada, y Filters es también una propiedad readonly que lee desde AppSettings.

 1
Author: Adam Cox,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-03-15 14:41:10

Estoy usando el servicio web en mi herramienta, donde esos servicios obtienen el procedimiento almacenado. mientras más cantidad de herramientas de cliente obtiene el servicio web, este problema surge. He corregido al especificar el atributo sincronizado para esas funciones que obtiene el procedimiento almacenado. ahora está funcionando bien, el error nunca apareció en mi herramienta.

 [MethodImpl(MethodImplOptions.Synchronized)]
 public static List<t> MyDBFunction(string parameter1)
  {
  }

Este atributo permite procesar una solicitud a la vez. así que esto resuelve el problema.

 0
Author: Pranesh Janarthanan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-12-28 04:10:36

Bueno para mí fue mi propio error. Estaba tratando de ejecutar un INSERT usando SqlCommand.executeReader() cuando debería haber estado usando SqlCommand.ExecuteNonQuery(). Se abrió y nunca se cerró, causando el error. Cuidado con este descuido.

 0
Author: Andrew Taylor,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-07-26 14:56:42

Esto se extrae de un escenario del mundo real:

  • El código funciona bien en un entorno de etapa con MultipleActiveResultSets se establece en la cadena de conexión
  • Código publicado en el entorno de producción sin MultipleActiveResultSets = true
  • Tantas páginas/llamadas funcionan mientras una sola falla
  • Mirando más de cerca la llamada, hay una llamada innecesaria hecho a la base de datos y necesita ser eliminado
  • Establecer MultipleActiveResultSets = true en Producción y publicación de código limpio, todo funciona bien y, eficientemente

En conclusión, sin olvidar MultipleActiveResultSets, el código podría haberse ejecutado durante mucho tiempo antes de descubrir una llamada redundante a la base de datos que podría ser muy costosa, y sugiero no depender completamente de establecer el atributo MultipleActiveResultSets, sino también averigüe por qué el código lo necesita donde falló.

 0
Author: usefulBee,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-09-06 17:54:02

Lo más probable es que este problema ocurra debido a la función de "carga lenta" de Entity Framework. Por lo general, a menos que se requiera explícitamente durante la búsqueda inicial, todos los datos unidos (cualquier cosa que se almacene en otras tablas de la base de datos) se obtiene solo cuando es necesario. En muchos casos eso es algo bueno, ya que evita obtener datos innecesarios y, por lo tanto, mejora el rendimiento de la consulta (sin uniones) y ahorra ancho de banda.

En la situación descrita en la pregunta, se realiza la búsqueda inicial, y durante "select" phase missing lazy loading data is requested, additional queries are issued and then EF is complaining about "open DataReader".

La solución propuesta en la respuesta aceptada permitirá la ejecución de estas consultas, y de hecho toda la solicitud tendrá éxito.

Sin embargo, si va a examinar las solicitudes enviadas a la base de datos, se dará cuenta de múltiples solicitudes - solicitud adicional para cada falta (carga perezosa) de datos. Esto podría ser un asesino de rendimiento.

Un mejor el enfoque es decirle a EF que precarga todos los datos cargados perezosamente necesarios durante la consulta inicial. Esto se puede hacer usando la instrucción "Include":

using System.Data.Entity;

query = query.Include(a => a.LazyLoadedProperty);

De esta manera, se realizarán todas las uniones necesarias y todos los datos necesarios se devolverán como una sola consulta. El problema descrito en la pregunta será resuelto.

 0
Author: Illidan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-03-31 10:45:43