Pourquoi puis-je avoir plusieurs lecteurs de données avec Dapper mais pas Entity Framework?

dapper database entity-framework

Question

J'ai commencé à développer une application à l'aide de Dapper, mais j'ai décidé que pour certaines requêtes, il serait intéressant d'utiliser Entity Framework. Donc, je suis en train de refactoriser certaines de mes requêtes. Dans les jours Dapper-only, j'avais un code similaire à ceci:

foreach (var itemFromDb in getRecordsWithDapper())
{
    var toInsert = doSomeComputations(itemFromDb);
    insertRecordWithDapper(toInsert);
}

C'était très utile, car peu importe la quantité de données dans ma base de données, je n'ai pas vraiment à me soucier de la mémoire. Je ne traite que d'un enregistrement à la fois.

Alors maintenant, j'ai refactorisé pour que ma requête fasse exactement la même chose, mais avec Entity Framework 6:

foreach (var itemFromDb in getRecordsWithEf())
{
    var toInsert = doSomeComputations(itemFromDb);
    insertRecordWithDapper(toInsert);
}

Cependant, je reçois maintenant une InvalidOperationException insertRecordWithDapper() dans insertRecordWithDapper() avec le message "Il existe déjà un DataReader ouvert associé à cette commande qui doit être fermé en premier." Je pourrais facilement résoudre ce problème en utilisant getRecordsWithEf().ToArray() , mais j'ai trop d’enregistrements pour les mettre en mémoire en une seule fois.

Donc, ceci est une question en deux parties:

  1. Pourquoi cela a-t-il cessé de fonctionner?
  2. Comment puis-je le réparer?

J'utilise actuellement SQL Server, même si j'aimerais une solution pour prendre en charge d'autres fournisseurs de bases de données.

Réponse acceptée

Parce que dapper suppose que la plupart des requêtes concernent des résultats limités, il est mis en mémoire tampon par défaut . Plutôt que de laisser le lecteur ouvert, il désérialise d’abord puis vous remet une liste. Vous devez spécifier un paramètre ( buffered ) pour le faire vous remettre un lecteur ouvert sur le flux TDS en direct. Bien qu'il soit important de prendre en charge des ensembles de données volumineux, il s'agit de l'exception et non de la norme. Par conséquent, dapper optimise les petits résultats par défaut.

On peut supposer que EF fait l’autre choix en vous offrant un lecteur ouvert par défaut. Pour compenser: appelez ToList ou similaire:

foreach (var itemFromDb in getRecordsWithEf().ToList())



Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Est-ce KB légal? Oui, apprenez pourquoi
Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Est-ce KB légal? Oui, apprenez pourquoi