229 votos

Ya hay un DataReader abierto asociado con este comando que primero se debe cerrar

Tengo esta consulta y me da 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)
        {
            var dateReported = (from h in context.AccountHistory
                                where h.CreditorRegistryId == creditorRegistryId && h.AccountNo == accountNo
                                select h.LastUpdated).Max();
            return dateReported;
        }

Error es:

Ya hay un DataReader abierto asociado con este comando que primero se debe cerrar.

[EDITAR]

seguimiento de la pila agregada:

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

574voto

Ladislav Mrnka Puntos 218632

Esto puede suceder si usted ejecuta una consulta mientras se itera sobre los resultados de otra consulta. No está claro a partir de su ejemplo donde esto sucede porque el ejemplo no es completa.

Una cosa que puede causar este es perezoso carga activa cuando se itera sobre los resultados de algunas de consulta.

Esto puede ser fácilmente solucionado por permitir a MARTE en la cadena de conexión. Agregue MultipleActiveResultSets=true para el proveedor de parte de su cadena de conexión (donde la Fuente de Datos, Catálogo Inicial, etc. se especifican).

66voto

Kisame Puntos 559

Puede utilizar el ToList() método antes de la return declaració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).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;
    }

4voto

James Alexander Puntos 2079

Parece que estás llamando DateLastUpdated desde dentro de una consulta activa el uso de la misma EF contexto y DateLastUpdate emite un comando para el almacén de datos en sí. Entity Framework admite sólo un comando activo por el contexto en un tiempo.

Puede refactorizar con sus dos consultas 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 me di cuenta de que usted está llamando a funciones como FormattedAccountNumber y FormattedRecordNumber en las consultas. A menos que estos se almacenan los procedimientos o funciones que has importado desde su base de datos en el modelo de datos de entidad y mapeado correcto, estos también se exceptúa a tirar como EF no sabe cómo traducir esas funciones en las declaraciones se pueden enviar al almacén de datos.

También tenga en cuenta, llamando AsEnumerable no forzar la consulta a ejecutar. Hasta la ejecución de la consulta es diferido hasta que se enumeran. Usted puede forzar la enumeración con ToList o ToArray si así lo desea.

3voto

Despertar Puntos 5365

En mi caso, usando Include() solucionado este error y dependiendo de la situación puede ser mucho más eficiente y luego emitir varias consultas cuando todo puede ser consultado 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);
            }
        }
    }
}

1voto

Ziggler Puntos 105

Yo sé si eso es respuesta duplicado o no. Si es que lo siento. Sólo quiero que los necesitados sepan cómo resolví mi problema utilizando ToList().

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

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

Resolví como abajo

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
}

Iteramos.com

Iteramos es una comunidad de desarrolladores que busca expandir el conocimiento de la programación mas allá del inglés.
Tenemos una gran cantidad de contenido, y también puedes hacer tus propias preguntas o resolver las de los demás.

Powered by:

X