2016-09-22 1 views
0

Je dois obtenir une grande quantité d'enregistrements différents (1000.000) de ma base de données pour construire un rapport à partir de ces données. Ma base de données est sur un système distant. Maintenant, j'ai des instructions sql différentes pour chaque rapport. Ces instructions sql sont envoyées au service. Le service remplit un DataSet et le renvoie à mon application. Maintenant, je peux lier le DataSet à mes rapports. Le problème est que DataSets avec le nombre d'enregistrements ont une énorme consommation de mémoire. Je veux dire que si je charge les données, la mémoire s'élève à 1 Go pour un chargement.Grandes données inconnues de DB à code

Existe-t-il une alternative pour charger des données sans cette consommation de mémoire? Je veux dire que j'utilise déjà ORM comme NHibernate, mais le problème est que je ne connais pas les données qui seront chargées, il y a des centaines de rapports avec différentes instructions sql qui peuvent être changées, donc je ne peux pas créer des centaines de classes ...

Edit:

Voici mon code exemple que j'utilise:

 DataSet dataSet = new DataSet(); 
    try 
    { 
     using (FbConnection connection = new FbConnection(strConnString)) 
     { 
      connection.Open(); 
      using (FbCommand cmd = 
       new FbCommand(
       "SELECT * FROM CUSTOMERS;", 
       connection)) 
      { 
       FbDataAdapter fbd = new FbDataAdapter(cmd); 
       fbd.Fill(dataSet); 
       // This is what the default ADO.Net provider can do.. 
       //SqlCommand command = new SqlCommand(queryString, connection); 
       //System.Xml.XmlReader reader = command.ExecuteXmlReader(); 
      } 
     } 

    } 
    catch (Exception ex) 
    { 

    } 

Répondre

0

la question que vous devriez poser est la suivante: quelle quantité de données est-il et quelle est la Overhead mémoire. Si le OVERHEAD est grand, vous devez trouver une meilleure structure de données. Si les DONNÉES elles-mêmes sont trop volumineuses pour la mémoire, vous devez explorer les moyens de n'en garder qu'une partie en mémoire à la fois. Dans les deux cas, utiliser NHibernate pour générer des rapports sur de tels volumes est douteux - il peut être utile d'utiliser des classes mappées existantes pour construire des requêtes, mais vous devez inclure une projection à une classe DTO simple non mappée ou à un objet [] ou similaire, pour éviter que NHibernate instancie des classes mappées pour tous les résultats - ce dernier serait mauvais pour les performances et la consommation de mémoire. Oh, et vouliez-vous dire que vous avez un service Web qui retourne un DataSet? Cela est considéré comme un mauvais style en général, car la classe DataSet est spécifique à Microsoft et pour diverses autres raisons (http://www.hanselman.com/blog/ReturningDataSetsFromWebServicesIsTheSpawnOfSatanAndRepresentsAllThatIsTrulyEvilInTheWorld.aspx).

+0

Le webservice est uniquement utilisé par mon application. Je dois charger les données de la base de données et un DataSet était la seule façon de le faire, par la façon dont j'utilise firebird et le fournisseur ADO.Net. Si je voudrais analyser le DataSet en XML ou JSON ou autre chose, il y aurait un problème de performance supplémentaire. Je veux dire s'il y a une possibilité de charger directement les données au format XML, ce qui serait mieux, mais rien trouvé jusqu'à présent. Le seul moyen est de le charger dans un DataSet, puis de l'écrire en XML. La classe SQLCommand oroginale a quelque chose comme un ExecuteXmlReader() mais il n'y a rien comme ce fournisseur Firebird (FBCommand). – Franki1986

+0

Quelque chose ne va pas ici ... La structure de retour de base de ADO.Net est un * DataReader *, pas un DataSet. Alors que le framework fournit des méthodes pratiques pour lire un DataReader dans un DataSet, à ma connaissance c'est quelque chose que l'utilisateur d'ADO.Net doit exécuter explicitement. –

+0

J'ai mis du code pour expliquer ce que je veux dire. – Franki1986