views:

1235

answers:

5

I'm trying to populate a DataTable, to build a LocalReport, using the following:

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);

At one point I noticed that the report was incomplete and it was missing one record. I've changed a few conditions so that the query would return exactly two rows and... surprise: The report shows only one row instead of two. I've tried to debug it to find where the problem is and I got stuck at

 dt.Load(cmd.ExecuteReader());

When I've noticed that the DataReader contains two records but the DataTable contains only one. By accident, I've added an ORDER BY clause to the query and noticed that this time the report showed correctly.

Apparently, the DataReader contains two rows but the DataTable only reads both of them if the SQL query string contains an ORDER BY (otherwise it only reads the last one). Can anyone explain why this is happening and how it can be fixed?

Edit: When I first posted the question, I said it was skipping the first row; later I realized that it actually only read the last row and I've edited the text accordingly (at that time all the records were grouped in two rows and it appeared to skip the first when it actually only showed the last). This may be caused by the fact that it didn't have a unique identifier by which to distinguish between the rows returned by MySQL so adding the ORDER BY statement caused it to create a unique identifier for each row.
This is just a theory and I have nothing to support it, but all my tests seem to lead to the same result.

A: 

Can you grab the actual query that is running from SQL profiler and try running it? It may not be what you expected.

Do you get the same result when using a SqlDataAdapter.Fill(dataTable)?

Have you tried different command behaviors on the reader? MSDN Docs

StingyJack
Yes, I've tried running the queries in a MySQL client. The only difference between them is that one has ORDER BY Invoice.ID and the other one doesn't, they both return two rows in the same order. I'm going to check on SqlDataAdapter now.
Tom
Any luck? You dont by chance have a TOP in the Query do you?
StingyJack
A: 

Not sure why you're missing the row in the datatable, is it possible you need to close the reader? In any case, here is how I normally load reports and it works every time...

        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))

Curious to see if it still happens.

thismat
A: 

Hey Tom,

Have you tried calling dt.AcceptChanges() after the dt.Load(cmd.ExecuteReader()) call to see if that helps?

Cheers Brian

Brian
No edits are performed.
Tom
+1  A: 

I had same issue. I took hint from your blog and put up the ORDER BY clause in the query so that they could form together the unique key for all the records returned by query. It solved the problem. Kinda weird.

Harshal
A: 

Hi guys,

In my case neither ORDER BY, nor dt.AcceptChanges() is working. I dont know why is that problem for. I am having 50 records in database but it only shows 49 in the datatable. skipping first row, and if there is only one record in datareader it shows nothing at all.

what a bizzareeee.....

canceriens
Next time, please post that as a comment or in the form of a question. This is not acceptable as an answer on StackOverflow.
Tom