104 votes

comment obtenir le nombre de lignes en utilisant SqlDataReader en C #

ma question est à propos de la façon d'obtenir le nombre de lignes à l'aide de SqlDataReader en C#. J'ai vu quelques réponses sur le net à ce sujet, mais aucun n'a été clairement définis, sauf un que les états de faire une boucle while avec la méthode Read() et incrémenter un compteur.

Mon problème est que je suis en train de remplir un tableau multidimensionnel avec la première ligne de l'en-tête de colonne les noms et chaque ligne après que l'être la ligne de données.

Je sais que je peux juste faire un dump de la substance dans un contrôle de Liste et vous inquiétez pas à ce sujet, mais pour ma propre édification et je tiens également à tirer les données dans et hors de la matrice comme je choisir et de les afficher dans des formats différents.

Je pense donc que je ne peux pas le Lire() et puis incrémentation ++ façon, parce que cela signifie que je dois ouvrir Read(); et ensuite, ouvrez Read(); nouveau pour obtenir la quantité de lignes, puis les données de la colonne.

Pas sûr, donc je me tourne vers toi!

Juste un petit exemple de ce dont je parle:

int counter = 0;    

while (sqlRead.Read())
{
    //get rows
    counter++
}

et puis une boucle for pour courir à travers les colonnes et pop

something.Read();

int dbFields = sqlRead.FieldCount;

for (int i = 0; i < dbFields; i++)
{
   // do stuff to array
}

103voto

Henk Holterman Points 153608

Il y a seulement deux options:

  • Vous le saurez en lisant toutes les lignes (et vous pouvez ainsi les stocker)

  • exécuter un spécialisé SELECT COUNT(*) de la requête à l'avance.

Aller deux fois à travers le DataReader boucle est vraiment trop cher, vous avez pour ré-exécuter la requête.

Et (merci à Pete OHanlon) la deuxième option est seulement de l'accès concurrentiel lorsque vous utilisez une transaction avec un Instantané ou RepeatableRead niveau d'isolation.

Puisque vous voulez finissent de stocker toutes les lignes dans la mémoire de toute façon la seule option raisonnable est de lire toutes les lignes dans un stockage flexible (List<>), puis copier les données dans le format que vous souhaitez. Le fonctionnement de la mémoire sera toujours beaucoup plus efficace.

13voto

AVD Points 57984

Classes relationnelles / DataSet est l'option appropriée.

 using (DataTable dt = new DataTable())
 {
  dt.Load(sqlRead);
  Console.WriteLine(dt.Rows.Count);
}
 

10voto

Pit Ming Points 66

Si vous n'avez pas besoin de récupérer toute la ligne et que vous voulez éviter de faire une double requête, vous pouvez probablement essayer quelque chose comme ça:

 using (var sqlCon = new SqlConnection("Server=127.0.0.1;Database=MyDb;User Id=Me;Password=glop;"))
      {
        sqlCon.Open();

        var com = sqlCon.CreateCommand();
        com.CommandText = "select * from BigTable";
        using (var reader = com.ExecuteReader())
        {
            //here you retrieve what you need
        }

        com.CommandText = "select @@ROWCOUNT";
        var totalRow = com.ExecuteScalar();

        sqlCon.Close();
      }
 

Vous devrez peut-être ajouter une transaction sans savoir si la réutilisation de la même commande ajoutera automatiquement une transaction dessus ...

8voto

Daniel Segan Points 144

Par-dessus, un ensemble de données ou dataset typé pourrait être une bonne temorary de la structure que vous pourriez utiliser pour faire votre filtrage. Un SqlDataReader est destiné à lire les données très rapidement. Pendant que vous êtes dans la boucle while() vous êtes toujours connecté à la base de données et il est en attente pour vous de faire ce que vous faites pour lire/processus le résultat suivant avant de poursuivre. Dans ce cas, vous pouvez obtenir de meilleures performances si vous tirez toutes les données, fermer la connexion à la DB et de traiter les résultats "hors ligne".

Les gens semblent déteste les jeux de données, de sorte que le ci-dessus pourrait être fait avec une collection d'objets fortement typés.

7voto

Pete OHanlon Points 7234

Vous ne pouvez pas obtenir un nombre de lignes directement à partir d'un lecteur de données parce que c'est ce qui est connu comme un curseur firehose - ce qui signifie que les données sont lues sur une rangée par rangée, sur la base de la lecture effectuée. Je vous le déconseille de faire 2 lit sur les données, car il y a la possibilité que les données ont changé entre faire les 2 lectures, et ainsi, vous obtiendrez des résultats différents.

Ce que vous pourriez faire est de lire les données dans une structure temporaire, et de l'utiliser à la place de la deuxième lecture. Sinon, vous aurez besoin de modifier le mécanisme par lequel vous pouvez récupérer les données et d'utiliser quelque chose comme un DataTable à la place.

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