J'essaie de vider une table de base de données à l'aide d'Entity Framework en C # en utilisant EF Version 6.1.1. Je m'attendais à ce que la boucle foreach charge chaque ligne une par une, mais elle charge progressivement toutes les lignes, puis manque de mémoire.
foreach (Quote L in context.Quotes)
sw.WriteLine(
"INSERT INTO [dbo].[Quote] ([QuoteId], [BookId], [VerbTenseId], [Form], [Quotation]) VALUES (%1,%2,%3,N'%4',N'%5')",
L.QuoteId, L.BookId, L.VerbTenseId, L.Form, L.Quotation);
Dans le code ci-dessus, contexte est un DatabaseContext qui a déjà été initialisé dans ma base de données et Quotes est une table valide d'enregistrements de devis. J'essaie de vider chaque enregistrement dans un fichier pour la sauvegarde. Évidemment (comme suggéré précédemment), je pourrais abandonner Entity Framework et utiliser un DataReader pour itérer la table de base de données, mais il est certain que ce framework permet l'itération de tables trop volumineuses pour tenir en mémoire.
Existe-t-il une manière élégante (peut-être un drapeau dans le contexte quelque part) qui permettrait cela?
Normalement, les ensembles de résultats sont faibles (quelques milliers) mais dans ce cas, ils atteignent des millions.
Il semble y avoir des options qui fonctionnaient avec les versions précédentes du framework, mais, à moins que je ne sois mal compris, ces méthodes et indicateurs n'existent plus.
Il ne s'agit que du code de test et non d'une sauvegarde régulière de la base de données. Je ne cherche pas un meilleur moyen d'exprimer mon code. Je cherche un moyen élégant d’utiliser EF. Si EF manque juste un tel support, c'est ma réponse.
S'il vous plaît, ne plaisantez pas avec l'exemple, indiquez simplement s'il existe un moyen d'utiliser EF pour énumérer une table de base de données sans charger chaque ligne en mémoire et la conserver. Je peux coder d'autres exemples et proposer d'autres options pour réaliser une sauvegarde de base de données. C'est seulement un exemple.
Je ne l'ai pas testé, mais essayez foreach (Quote L in context.Quotes.AsNoTracking()) {...}
. .AsNoTracking()
ne devrait pas mettre les entités en cache, donc je suppose qu'elles seront consommées par GC quand elles sortiront de la portée.
Une autre solution consisterait à implémenter le traitement par lots (sélectionner N premières entités, traiter, sélectionner suivant N supérieur). Dans ce cas, assurez-vous de disposer et de créer un nouveau contexte à chaque itération et d'utiliser OrderBy () dans la requête.