2017-07-20 2 views
0

Je suis en train de faire une migration et j'ai rencontré une mauvaise performance lorsque j'ai essayé d'obtenir des données du serveur SQL. La façon dont je fais est:OutOfMemoryException avec requête SQL obtenant une grande quantité de données à partir de SQL Server

ctx.ExampleEntity.Database.SQLQuery<ClassConverter>("Select....") 

ClassConverter est une classe qui n'a aucun rapport avec le ExampleEntity. Le problème est que je reçois plus de 1,5 millions d'enregistrements de cette requête et quand il essaie de créer la liste, il lance un OutOfMemoryException et je ne suis pas en mesure d'éviter cela.

C'est l'EF 6.0.

/////////////////////////////////// Solution

Suite à la réponse de Mayu, J'ai écrit ce code, avec 1M il ne jette pas l'exception. Le sql renvoie les enregistrements qui ne sont pas dans la base de données finale.

List<ClassConverter> listRowsToInsert = new List<ClassConverter>(); 
int countRecords=-1; 
int skipCount = 0; 
while(countRecords!=0){ 
    List<ClassConverter> listIndivInsert = genEntitAgp.Database.SqlQuery<ClassConverter>(File.ReadAllText("sql/limitPfm.sql")).Skip(skipCount).Take(1000000).ToList(); 
    countRecords = listIndivInsert.Count(); 
    listRowsToInsert.AddRange(listIndivInsert); 
    if (countRecords < 1000000) 
     countRecords = 0; 
    skipCount += 1000000; 
} 

Des idées?

Merci pour tous

+0

Avez-vous vraiment besoin d'un million d'enregistrements à la fois? – mason

+0

Divisez l'appel en lots? –

+0

S'il n'y a pas de relation, cela peut renvoyer une jointure croisée, ce qui signifie que chaque ligne d'une table est associée à chaque ligne de la seconde table. Si chaque table a 1000 lignes, c'est 1,000,000 lignes retournées. Si vous ne faites aucune jointure et que la table ne contient que 1,5 million de lignes, vous devez effectuer un chargement paresseux ou un chargement par lots, ou mieux filtrer. – pmbAustin

Répondre

0

Si vous utilisez EF 6.0 vous pouvez mapper l'entité, puis de les traiter par lots avec db.Records.Skip(n).Take(m)?

+0

Cela fonctionne! J'ai mis mon code sur la question;) – kartGIS

+1

Cette pagination simple n'a qu'un inconvénient - vous pouvez obtenir des enregistrements dupliqués ou manquants si les données changent. –