Tom*_*Tom 20 .net datatable datareader localreport
我正在尝试使用以下内容填充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);
Run Code Online (Sandbox Code Playgroud)
有一次,我注意到报告不完整,缺少一条记录.我已经改变了一些条件,以便查询将返回两行并且... 惊讶:报告只显示一行而不是两行.我试图调试它以找出问题所在,我陷入了困境
dt.Load(cmd.ExecuteReader());
Run Code Online (Sandbox Code Playgroud)
当我注意到它DataReader包含两个记录但DataTable只包含一个.不小心,我ORDER BY在查询中添加了一个子句,并注意到这次报告正确显示.
显然,DataReader包含两行,但是如果SQL查询字符串包含一行,则DataTable只读取它们ORDER BY(否则它只读取最后一行).任何人都可以解释为什么会发生这种情况以及如何解决这个问题?
编辑:
当我第一次发布问题时,我说它正在跳过第一行; 后来我意识到它实际上只读了最后一行并且我相应地编辑了文本(当时所有的记录都被分成两行,当它实际上只显示最后一行时它似乎跳过了第一行).这可能是因为它没有唯一的标识符来区分MySQL返回的行,因此添加ORDER BY语句会导致它为每行创建唯一标识符.
这只是一个理论,我没有什么可以支持它,但我所有的测试似乎都会导致相同的结果.
这个问题已有几年了,但除了上面提到的解决方法外,我还没有找到合适的答案.
在摆弄了相当多的东西之后,我发现DataTable.Load方法需要底层数据中的主键列.如果您仔细阅读文档,这很明显,尽管没有明确说明.
如果你有一个名为"id"的列,它似乎使用它(它为我修复了它).否则,它似乎只是使用第一列,无论它是否唯一,并在读取时覆盖该列中具有相同值的行.如果您没有名为"id"的列并且您的第一列不是唯一的,我建议在加载datareader之前尝试显式设置数据表的主键列.
小智 6
为了防止任何人遇到像癌症一样的问题,我在调用Doh 之前使用If DataReader.Read而不是If DataReader.HasRows检查存在dt.load(DataReader)!