22

我正在尝试使用以下内容填充 DataTable 以构建 LocalReport:

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

有一次,我注意到报告不完整,并且缺少一条记录。我更改了一些条件,以便查询将准确返回两行并且...惊喜:报告仅显示一行而不是两行。我试图调试它以找出问题所在,但我陷入了困境

 dt.Load(cmd.ExecuteReader());

当我注意到DataReader包含两条记录但DataTable仅包含一条时。偶然地,我ORDER BY在查询中添加了一个子句,并注意到这次报告正确显示。

显然,DataReader 包含两行,但 DataTable 仅在 SQL 查询字符串包含时读取这两行ORDER BY(否则它只读取最后一行)。谁能解释为什么会发生这种情况以及如何解决?

编辑: 当我第一次发布问题时,我说它跳过了第一行;后来我意识到它实际上只读取了最后一行,并且我已经相应地编辑了文本(当时所有记录都分为两行,当它实际上只显示最后一行时,它似乎跳过了第一行)。这可能是由于它没有唯一标识符来区分 MySQL 返回的行,因此添加ORDER BY语句会导致它为每行创建唯一标识符。
这只是一个理论,我没有任何证据支持它,但我所有的测试似乎都得出了相同的结果。

4

14 回答 14

9

After fiddling around quite a bit I found that the DataTable.Load method expects a primary key column in the underlying data. If you read the documentation carefully, this becomes obvious, although it is not stated very explicitly.

If you have a column named "id" it seems to use that (which fixed it for me). Otherwise, it just seems to use the first column, whether it is unique or not, and overwrites rows with the same value in that column as they are being read. If you don't have a column named "id" and your first column isn't unique, I'd suggest trying to explicitly set the primary key column(s) of the datatable before loading the datareader.

于 2012-02-09T11:43:07.600 回答
6

Just in case anyone is having a similar problem as canceriens, I was using If DataReader.Read ... instead of If DataReader.HasRows to check existence before calling dt.load(DataReader) Doh!

于 2011-01-09T17:18:06.357 回答
4

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.

于 2009-01-17T07:59:02.763 回答
4

Had the same issue. It is because the primary key on all the rows is the same. It's probably what's being used to key the results, and therefore it's just overwriting the same row over and over again.

Datatables.Load points to the fill method to understand how it works. This page states that it is primary key aware. Since primary keys can only occur once and are used as the keys for the row ...

"The Fill operation then adds the rows to destination DataTable objects in the DataSet, creating the DataTable objects if they do not already exist. When creating DataTable objects, the Fill operation normally creates only column name metadata. However, if the MissingSchemaAction property is set to AddWithKey, appropriate primary keys and constraints are also created." (http://msdn.microsoft.com/en-us/library/zxkb3c3d.aspx)

于 2012-02-28T20:51:16.927 回答
4

Don't use

dr.Read()

Because It moves the pointer to the next row. Remove this line hope it will work.

于 2013-12-09T13:23:47.503 回答
4

Came across this problem today.

Nothing in this thread fixed it unfortunately, but then I wrapped my SQL query in another SELECT statement and it work!

Eg:

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

Strange....

于 2014-04-15T12:16:47.710 回答
1

你能抓住从 SQL 探查器运行的实际查询并尝试运行它吗?这可能不是你所期望的。

使用 SqlDataAdapter.Fill(dataTable) 时是否得到相同的结果?

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

于 2008-10-23T11:52:16.620 回答
1

I know this is an old question, but for me the think that worked whilst querying an access database and noticing it was missing 1 row from query, was to change the following:-

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

    if(dataset.hasrows) - Missing row appears.
于 2016-04-28T08:52:57.540 回答
1

For anyone else that comes across this thread as I have, the answer regarding the DataTable being populated by a unique ID from MySql is correct.

However, if a table contains multiple unique IDs but only a single ID is returned from a MySql command (instead of receiving all Columns by using '*') then that DataTable will only organize by the single ID that was given and act as if a 'GROUP BY' was used in your query.

So in short, the DataReader will pull all records while the DataTable.Load() will only see the unique ID retrieved and use that to populate the DataTable thus skipping rows of information

于 2019-10-22T17:46:08.457 回答
0

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.

于 2008-10-27T21:15:32.997 回答
0

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

于 2008-10-28T14:37:31.317 回答
0

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

于 2010-08-03T16:50:23.803 回答
0

I know this is an old question, but I was experiencing the same problem and none of the workarounds mentioned here did help.

In my case, using an alias on the colum that is used as the PrimaryKey solved the issue.

So, instead of

SELECT a
     , b
FROM table

I used

SELECT a as gurgleurp
     , b
FROM table

and it worked.

于 2014-03-26T14:54:33.023 回答
0

I had the same problem.. do not used dataReader.Read() at all.. it will takes the pointer to the next row. Instead use directly datatable.load(dataReader).

于 2014-10-09T11:12:59.357 回答