Question

J'essaie de renseigner un DataTable pour créer un rapport local à l'aide des éléments suivants:

MySqlCommand cmd = new MySqlCommand();
cmd.Connection = new MySqlConnection(Properties.Settings.Default.dbConnectionString);
cmd.CommandType = CommandType.Text;
cmd.CommandText = "SELECT ... LEFT JOIN ... WHERE ..."; /* query snipped */

// prepare data
dataTable.Clear();
cn.Open();
// fill datatable
dt.Load(cmd.ExecuteReader());
// fill report
rds = new ReportDataSource("InvoicesDataSet_InvoiceTable",dt);
reportViewerLocal.LocalReport.DataSources.Clear();
reportViewerLocal.LocalReport.DataSources.Add(rds);

À un moment donné, j’ai remarqué que le rapport était incomplet et qu’il manquait un enregistrement. J'ai modifié quelques conditions afin que la requête renvoie exactement deux lignes et ... surprise : le rapport n'affiche qu'une seule ligne au lieu de deux. J'ai essayé de le déboguer pour trouver où se trouvait le problème et je me suis retrouvé coincé à

 dt.Load(cmd.ExecuteReader());

Lorsque j'ai remarqué que DataReader contient deux enregistrements mais que DataTable n'en contient qu'un. J'ai accidentellement ajouté une clause ORDER BY à la requête et constaté que le rapport était correctement affiché cette fois-ci.

Apparemment, le DataReader contient deux lignes, mais le DataTable ne les lit que si la chaîne de requête SQL contient un ORDER BY (sinon, il ne lit que la dernière). Quelqu'un peut-il expliquer pourquoi cela se produit et comment il peut être corrigé?

Modifier: Quand j'ai posté la question pour la première fois, j'ai dit qu'il sautait la première ligne; plus tard, j'ai réalisé qu'il ne lisait en réalité que la dernière ligne et que j'avais édité le texte en conséquence (à ce moment-là, tous les enregistrements ont été regroupés sur deux lignes et il est apparu que le premier sautait alors qu'il ne montrait que le dernier). Cela peut être dû au fait qu’il n’avait pas d’identifiant unique permettant de distinguer les lignes renvoyées par MySQL. L’ajout de l’instruction ORDER BY a donc entraîné la création d’un identifiant unique pour chaque ligne.
Ceci n’est qu’une théorie et je n’ai rien à faire, mais tous mes tests semblent aboutir au même résultat.

Était-ce utile?

La solution

J'ai eu le même problème. Je me suis inspiré de votre blog et ai mis en place la clause ORDER BY dans la requête afin qu’ils puissent former ensemble la clé unique de tous les enregistrements renvoyés par requête. Cela a résolu le problème. Un peu bizarre.

Autres conseils

La question a plusieurs années, mais je n’avais pas trouvé de réponse décente, autre que la solution susmentionnée.

Après avoir bricolé un peu, j'ai constaté que la méthode DataTable.Load attend une colonne de clé primaire dans les données sous-jacentes. Si vous lisez attentivement la documentation, cela devient évident, bien que cela ne soit pas indiqué très explicitement.

Si vous avez une colonne nommée " id " il semble utiliser cela (ce qui l'a corrigé pour moi). Sinon, il semble simplement utiliser la première colonne, qu'elle soit unique ou non, et écrase les lignes ayant la même valeur dans cette colonne lors de leur lecture. Si vous ne disposez pas d'une colonne nommée " id " et que votre première colonne n’est pas unique, nous vous conseillons d’essayer de définir explicitement la ou les colonnes de clé primaire du datatable avant de charger le datareader.

Juste au cas où quelqu'un aurait un problème similaire à canceriens, j'utilisais If DataReader.Read ... au lieu de If DataReader.HasRows pour vérifier l'existence avant d'appeler dt.load (DataReader) Doh!

Avait le même problème. C'est parce que la clé primaire sur toutes les lignes est la même. C’est probablement ce qui est utilisé pour entrer les résultats, et par conséquent, il écrase la même ligne encore et encore.

Datatables.Load pointe sur la méthode de remplissage pour comprendre son fonctionnement. Cette page indique qu'il est conscient de la clé primaire. Comme les clés primaires ne peuvent apparaître qu'une seule fois et sont utilisées comme clés pour la ligne ...

" L'opération de remplissage ajoute ensuite les lignes aux objets DataTable de destination dans le DataSet, en créant les objets DataTable s'ils n'existent pas déjà. Lors de la création d'objets DataTable, l'opération de remplissage crée normalement uniquement les métadonnées de nom de colonne. Toutefois, si la propriété MissingSchemaAction est définie sur AddWithKey, des clés primaires et des contraintes appropriées sont également créées. (http://msdn.microsoft.com/en-us/library/zxkb3c3d.aspx)

Nous sommes tombés sur ce problème aujourd'hui.

Malheureusement, dans ce fil de discussion, rien n'a été corrigé, mais j'ai ensuite intégré ma requête SQL dans une autre instruction SELECT et cela fonctionne!

Par exemple:

SELECT * FROM (
    SELECT ..... < YOUR NORMAL SQL STATEMENT HERE />
) allrecords

Étrange ....

Ne pas utiliser

dr.Read()

Parce que cela déplace le pointeur sur la ligne suivante. Supprimez cette ligne en espérant que cela fonctionnera.

Pouvez-vous récupérer la requête qui est en cours d’exécution à partir du profileur SQL et essayer de l’exécuter? Ce n'est peut-être pas ce que vous attendiez.

Obtenez-vous le même résultat lorsque vous utilisez un SqlDataAdapter.Fill (dataTable)?

Avez-vous essayé différents comportements de commande sur le lecteur? Documents MSDN

Je sais que c’est une vieille question, mais pour moi, l’idée qui fonctionnait lorsqu’on interrogeait une base de données d’accès en remarquant qu’il manquait une ligne de la requête était de changer les éléments suivants: -

    if(dataset.read())  - Misses a row.

    if(dataset.hasrows) - Missing row appears.

Vous ne savez pas pourquoi la ligne du datatable manque dans la rangée, est-il possible que vous ayez besoin de fermer le lecteur? Dans tous les cas, voici comment je charge normalement les rapports et cela fonctionne à chaque fois ...

        Dim deals As New DealsProvider()
        Dim adapter As New ReportingDataTableAdapters.ReportDealsAdapter
        Dim report As ReportingData.ReportDealsDataTable = deals.GetActiveDealsReport()
        rptReports.LocalReport.DataSources.Add(New ReportDataSource("ActiveDeals_Data", report))

Curieux de voir si cela se produit encore.

Dans mon cas, ni ORDER BY, ni dt.AcceptChanges () ne fonctionnent. Je ne sais pas pourquoi ce problème est pour. J'ai 50 enregistrements dans la base de données, mais il ne montre que 49 dans le datatable. en sautant la première ligne, et s’il n’ya qu’un seul enregistrement dans le datareader, il n’affiche rien du tout.

quel bizzareeee .....

Avez-vous essayé d'appeler dt.AcceptChanges () après l'appel dt.Load (cmd.ExecuteReader ()) pour voir si cela vous aiderait?

Je sais que c’est une vieille question, mais j’ai eu le même problème et aucune des solutions de contournement mentionnées ici n’a aidé.

Dans mon cas, l'utilisation d'un alias sur la colonne utilisée comme PrimaryKey a résolu le problème.

Donc, au lieu de

SELECT a
     , b
FROM table

j'ai utilisé

SELECT a as gurgleurp
     , b
FROM table

et cela a fonctionné.

J'ai eu le même problème .. ne pas utiliser dataReader.Read () du tout .. cela amènera le pointeur à la ligne suivante. Utilisez plutôt directement datatable.load (dataReader).

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top