Il existe déjà un DataReader ouvert associé à cette commande qui doit être fermé en premier

J’ai cette requête et j’obtiens l’erreur dans cette fonction:

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, ssortingng accountNo) { return (from h in context.AccountHistory where h.CreditorRegistryId == creditorRegistryId && h.AccountNo == accountNo select h.LastUpdated).Max(); } 

L’erreur est:

Il existe déjà un DataReader ouvert associé à cette commande qui doit être fermé en premier.

Mettre à jour:

trace de stack ajoutée:

 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(Ssortingng method, SqlCommand command) +23 System.Data.SqlClient.SqlCommand.ValidateCommand(Ssortingng method, Boolean async) +144 System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Ssortingng method, DbAsyncResult result) +87 System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Ssortingng method) +32 System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior behavior, Ssortingng 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.GetEnumerator() +38 System.Linq.Enumerable.Single(IEnumerable`1 source) +114 System.Data.Objects.ELinq.ObjectQueryProvider.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, Ssortingng accountNo) in D:\Freelance Work\SuperExpert\CreditRegistry\CreditRegistry\Repositories\CreditRegistryRepository.cs:1497 CreditRegistry.Repositories.CreditRegistryRepository.b__88(AccountsReport account, Int32 index) in D:\Freelance Work\SuperExpert\CreditRegistry\CreditRegistry\Repositories\CreditRegistryRepository.cs:1250 System.Linq.d__7`2.MoveNext() +198 System.Linq.Buffer`1..ctor(IEnumerable`1 source) +217 System.Linq.d__0.MoveNext() +96 

Cela peut se produire si vous exécutez une requête en itérant les résultats d’une autre requête. Votre exemple n’indique pas clairement où cela se produit car l’exemple n’est pas complet.

Une chose qui peut causer ceci est le chargement paresseux déclenché lors d’une itération sur les résultats d’une requête.

Cela peut être facilement résolu en autorisant l’utilisation de MARS dans votre chaîne de connexion. Ajoutez MultipleActiveResultSets=true à la partie fournisseur de votre chaîne de connexion (où la source de données, le catalogue initial, etc. sont spécifiés).

Vous pouvez utiliser la méthode ToList() avant l’instruction 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, ssortingng accountNo) { var dateReported = (from h in context.AccountHistory where h.CreditorRegistryId == creditorRegistryId && h.AccountNo == accountNo select h.LastUpdated).Max(); return dateReported; } 

Voici une chaîne de connexion fonctionnelle pour quelqu’un qui a besoin de référence.

     

Dans mon cas, l’utilisation de Include() résolu cette erreur et, selon la situation, elle peut être beaucoup plus efficace que l’envoi de plusieurs requêtes en même temps que la jointure.

 IEnumerable 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); } } } } 

utilisez la syntaxe .ToList() pour convertir l’object lu de la firebase database en liste pour éviter d’être relu de nouveau. Espérons que cela fonctionnerait pour cela. Merci.

Je ne sais pas si c’est une réponse en double ou non. Si c’est le cas, je suis désolé. Je veux juste que les nécessiteux sachent comment j’ai résolu mon problème en utilisant ToList ().

Dans mon cas, j’ai eu la même exception pour la requête ci-dessous.

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

J’ai résolu comme ci-dessous

 List 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 } 

Il semble que vous appeliez DateLastUpdated depuis une requête active en utilisant le même contexte EF et DateLastUpdate envoie une commande au magasin de données lui-même. Entity Framework ne prend en charge qu’une seule commande active par contexte à la fois.

Vous pouvez modifier vos deux requêtes ci-dessus en une seule comme celle-ci:

 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); 

J’ai également remarqué que vous appelez des fonctions comme FormattedAccountNumber et FormattedRecordNumber dans les requêtes. À moins que ces procédures ou fonctions stockées dans votre modèle de données d’entité ne soient imscopes de votre firebase database et mappées correctement, elles renverront également des exemples, car EF ne saura pas comment traduire ces fonctions en instructions pouvant être envoyées au magasin de données.

Notez également que l’appel à AsEnumerable ne force pas l’exécution de la requête. Jusqu’à ce que l’exécution de la requête soit différée jusqu’à l’énumération. Vous pouvez forcer l’énumération avec ToList ou ToArray si vous le souhaitez.

En plus de la réponse de Ladislav Mrnka :

Si vous publiez et remplacez le conteneur dans l’onglet Paramètres , vous pouvez définir MultipleActiveResultSet sur True. Vous pouvez trouver cette option en cliquant sur Avancé … et ce sera sous Groupe avancé .

J’ai eu la même erreur, lorsque j’ai essayé de mettre à jour certains enregistrements dans la boucle de lecture. J’ai essayé la réponse la plus votée MultipleActiveResultSets=true et trouvé, que c’est juste une solution pour obtenir la prochaine erreur

La nouvelle transaction n’est pas autorisée car d’autres threads sont en cours d’exécution dans la session

La meilleure approche, qui fonctionnera pour les ResultSets volumineux, consiste à utiliser des blocs et à ouvrir un contexte distinct pour chaque bloc, comme décrit dans SqlException à partir d’Entity Framework – Une nouvelle transaction n’est pas autorisée car d’autres threads s’exécutent dans la session

J’ai résolu ce problème en changeant wait _accountSessionDataModel.SaveChangesAsync (); à _accountSessionDataModel.SaveChanges (); dans ma classe de référentiel

  public async Task CreateSession() { var session = new Session(); _accountSessionDataModel.Sessions.Add(session); await _accountSessionDataModel.SaveChangesAsync(); } 

Changé en:

  public Session CreateSession() { var session = new Session(); _accountSessionDataModel.Sessions.Add(session); _accountSessionDataModel.SaveChanges(); } 

Le problème était que j’ai mis à jour les sessions dans l’interface après avoir créé une session (dans le code), mais parce que SaveChangesAsync se produit de manière asynchrone, l’extraction des sessions provoquait cette erreur, car l’opération SaveChangesAsync n’était pas encore prête.

Pour ceux qui trouvent cela via Google;
J’obtiens cette erreur car, comme le suggère l’erreur, je n’ai pas réussi à fermer SqlDataReader avant d’en créer une autre sur le même SqlCommand, en supposant à tort qu’elle serait récupérée en quittant la méthode dans laquelle elle a été créée.

J’ai résolu le problème en appelant sqlDataReader.Close(); avant de créer le deuxième lecteur.

Dans mon cas, j’avais ouvert une requête à partir d’un contexte de données, comme

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

… et ensuite interrogé le même …

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

Ajouter le .ToList au premier a résolu mon problème. Je pense qu’il est logique d’envelopper ceci dans une propriété comme:

 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 

Où _stores est une variable privée et Filters est également une propriété en lecture seule qui lit à partir de AppSettings.

J’utilise le service Web dans mon outil, où ces services récupèrent la procédure stockée. alors que plus d’outil client récupère le service Web, ce problème se pose. J’ai corrigé en spécifiant l’atsortingbut Synchronized pour que cette fonction récupère la procédure stockée. maintenant ça marche bien, l’erreur ne s’est jamais manifestée dans mon outil.

  [MethodImpl(MethodImplOptions.Synchronized)] public static List MyDBFunction(ssortingng parameter1) { } 

Cet atsortingbut permet de traiter une requête à la fois. donc cela résout le problème.

Eh bien pour moi, c’était mon propre bug. J’essayais d’exécuter INSERT utilisant SqlCommand.executeReader() alors que j’aurais dû utiliser SqlCommand.ExecuteNonQuery() . Il a été ouvert et n’a jamais été fermé, provoquant l’erreur. Attention à cette omission.

Ceci est extrait d’un scénario réel:

  • Le code fonctionne bien dans un environnement de scène avec MultipleActiveResultSets défini dans la chaîne de connexion
  • Code publié dans l’environnement de production sans MultipleActiveResultSets = true
  • Tant de pages / appels fonctionnent pendant qu’un seul échoue
  • En regardant de plus près l’appel, il y a un appel inutile à la firebase database et doit être supprimé
  • Définissez MultipleActiveResultSets = true dans Production et publiez du code nettoyé, tout fonctionne bien et efficacement

En conclusion, sans oublier MultipleActiveResultSets, le code peut avoir fonctionné longtemps avant de découvrir un appel redondant de la firebase database qui pourrait être très coûteux, et je suggère de ne pas dépendre entièrement de l’atsortingbut MultipleActiveResultSets mais aussi de savoir pourquoi le code en a besoin où il a échoué .

Très probablement, ce problème se produit à cause de la fonctionnalité de “chargement différé” d’Entity Framework. Généralement, à moins que cela ne soit requirejs explicitement lors de la récupération initiale, toutes les données jointes (toutes les données stockées dans les autres tables de la firebase database) ne sont récupérées que lorsque cela est requirejs. Dans de nombreux cas, c’est une bonne chose car cela empêche de récupérer des données inutiles et améliore ainsi les performances des requêtes (pas de jointures) et économise de la bande passante.

Dans la situation décrite dans la question, l’extraction initiale est effectuée et pendant la phase “select”, des données de chargement paresseux manquantes sont demandées, des requêtes supplémentaires sont émises et EF se plaint de “open DataReader”.

La solution proposée dans la réponse acceptée permettra l’exécution de ces requêtes, et toute la demande réussira.

Toutefois, si vous examinez les demandes envoyées à la firebase database, vous remarquerez plusieurs demandes – une requête supplémentaire pour chaque donnée manquante (chargée paresseuse). Cela pourrait être un tueur de performance.

Une meilleure approche consiste à indiquer à EF de précharger toutes les données chargées paresseuses nécessaires lors de la requête initiale. Cela peut être fait en utilisant la déclaration “Include”:

 using System.Data.Entity; query = query.Include(a => a.LazyLoadedProperty); 

De cette façon, toutes les jointures nécessaires seront effectuées et toutes les données nécessaires seront renvoyées sous la forme d’une requête unique. Le problème décrit dans la question sera résolu.