147 votes

Une nouvelle transaction n'est pas autorisée car d'autres threads sont en cours d'exécution dans la session LINQ To Entity.

Avez-vous une idée de la raison pour laquelle cela pourrait être cassé ?

foreach (var p in pp)
{
    ProjectFiles projectFile = (ProjectFiles)p;
    projectFile.Status = Constants.ProjectFiles_ERROR;
    projectFile.DateLastUpdated = DateTime.Now;
    context.SaveChanges();
}

J'ai lu que la solution au problème est de récupérer les résultats en une seule fois avant la boucle foreach.

Mais je ne l'ai pas fait ? "pp" est la collection de résultats dans mon cas

11 votes

Est pp le résultat d'une requête linq ? Si c'est le cas, vous devrez peut-être faire un ToList() sur lui pour le déconnecter de la base de données avant d'exécuter votre boucle.

0 votes

Oui, c'est ça. Ok, je vais essayer ça.

2 votes

appeler sauvegarder les changements en dehors de la boucle

376voto

Guffa Points 308133

Le site pp n'est pas une collection d'objets, c'est un énumérateur qui peut retourner des objets. Pendant que vous utilisez l'énumérateur, la source doit rester ouverte.

Utilisez le ToList pour réaliser l'énumérateur dans une collection. Cela va lire tous les éléments de l'énumérateur et fermer la connexion à la source, de sorte que vous pouvez utiliser la connexion pour d'autres choses.

foreach (var p in pp.ToList())

18 votes

Dieu vous bénisse @Guffa ! !! +1

2 votes

Génial ! Cela fonctionne aussi avec pp.ToArray()

2 votes

Ricardo, cela fonctionne tant que ce n'est pas IQueryable.

10voto

Juann Strauss Points 1677

Une façon de contourner ce problème est d'appeler .ToList() sur votre collection avant de l'itérer.

Et pendant que vous y êtes, appelez context.SaveChanges() seulement une fois après la sortie de la boucle pour accélérer le code.

1 votes

Cette déclaration ne semble pas décrire la situation réelle, sur la base des affirmations de la solution acceptée et de celles fournies dans l'autre question à laquelle il a été répondu, dont le lien figure en haut de cette question. Il semble qu'il s'agisse plutôt d'une tentative de sauvegarde des modifications avant la fin de l'itération que de l'utilisation de connexions multiples.

0 votes

Oui, il n'y a pas plusieurs connexions en cours. Il s'agit de lire à partir d'une connexion tout en essayant d'écrire dessus.

0 votes

Mais si j'itère sur un million d'éléments, je ne peux pas tous les charger en mémoire. Il doit y avoir un moyen de faire des mises à jour tout en continuant à itérer.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X