DataTable.Load(FbDataReader) 不会将所有内容加载到 DataTable
Posted
技术标签:
【中文标题】DataTable.Load(FbDataReader) 不会将所有内容加载到 DataTable【英文标题】:DataTable.Load(FbDataReader) does not load everything into DataTable 【发布时间】:2014-05-05 00:24:11 【问题描述】:这里有一个密切相关的问题:.NET DataTable skips rows on Load(DataReader)
我有一个返回 169 个结果的 SQL 查询。结果如下所示:
CustomerID Customer Name TerminalID Creation Date
1 First Customer 12345 2010-07-07
1 First Customer 12346 2010-07-07
1 First Customer 12347 2010-07-07
2 Second Customer 23456 2011-04-18
这个结果是正确的。
我在一个 C# 程序中输入查询并像这样执行它:
public DataTable getDataTableFromSql(FbCommand command)
// Create a new datatable
DataTable result = new DataTable();
// Set up the connection
using (FbConnection con = new FbConnection(this.connectionString))
// Open the connection
con.Open();
// Set up the select command
FbCommand sqlCmd = command;
// Add the connection to it
sqlCmd.Connection = con;
try
// Get the results
using (FbDataReader sqlReader = sqlCmd.ExecuteReader())
// Load the results into the table
result.Load(sqlReader);
catch (Exception ex)
Console.WriteLine(ex);
// Return the table
return result;
此代码经过测试,适用于许多不同的 SQL 查询。
但对于上述查询,DataTable
仅包含 39 个结果,如下所示:
CustomerID Customer Name TerminalID Creation Date
1 First Customer 12347 2010-07-07
2 Second Customer 23456 2011-04-18
我稍微摆弄了一下代码,这是我目前发现的:FbDataReader
正确地从数据库中获取结果。如果我只查询TerminalID
,我最终会在DataTable
中得到169 个结果。如果我查询CustomerID
,我会收到 39 个结果。
结论:result.Load(sqlReader)
行将CustomerID
的结果分组并丢弃所有其他结果,无论它们是否可以分组。
为什么会这样?如何将我的查询结果加载到DataTable
而不会由于不合逻辑的分组而“丢失”任何行?为什么DataTable
首先“分组”了结果?
注意:我还尝试了所有三个可用于DataTables
的LoadOptions
,结果都相同:只有 39 个结果加载到 DataTable
。
【问题讨论】:
你试过用dataadapter填充吗? 什么意思 " 如果我只查询 TerminalID"?如果您查看DataTable
内容,您在哪里以及如何查询它?
@TimSchmelter:这意味着我编辑了我的 SQL 查询,以便它只返回列 TerminalId
。当我再次运行程序时,我在DataTable
中收到所有 169 个结果。
@waka:DataReader
返回多少条记录?您是否在循环中使用了int
变量(while(sqlReader.Read()count++;)
)来查看数据库返回 39 条还是 169 条记录?那么你至少会知道你的问题是与DataTable.Load
有关还是与查询有关。
.NET DataTable skips rows on Load(DataReader)的可能重复
【参考方案1】:
DataTable.Load
方法需要基础数据中的主键列(即来自DataReader
)。看起来您的过程没有任何主键列,或者如果您有一个,请在 sql 语句中使用order by
,以便DataTable
能够接受它作为主键。
这是DataTable.Load
的一个非常古老的问题,并且没有很好的记录。一般SQLDataAdapter
配DataTable
比较好。
在您的情况下,我认为一旦 Load 找到重复项,它就会停止加载数据。我没有在任何地方得到这个记录,但看起来像这个问题。
【讨论】:
【参考方案2】:即使我不知道问题所在,我也建议改用DataAdapter
。也许可行:
// Get the results
using(var da = new FbDataAdapter(sqlCmd))
// Load the results into the table
da.Fill(result);
为什么会这样?我认为 this answer 在另一个问题中解释了它。
【讨论】:
我刚刚对此进行了测试,我在DataTable
中得到了 169 个结果,谢谢!我真的很想知道为什么DataTable.Load()
似乎“吞下了”一些结果...:/
@waka:这是一个类似的问题:***.com/questions/229425/…
谢谢,我想我现在知道会发生什么了。我将编辑我的问题以包含我的想法。【参考方案3】:
问题的思路如下:
DataTable.Load()
在结果中查找主键。如果它尝试加载到DataTable
的主键已经存在于该表中,它会用新结果覆盖该行。
但是,为具有 主键 的列使用不同的别名确实可以解决问题,所有结果都将加载到 DataTable
,因为似乎该列是主键被别名覆盖。
【讨论】:
以上是关于DataTable.Load(FbDataReader) 不会将所有内容加载到 DataTable的主要内容,如果未能解决你的问题,请参考以下文章
映射如何通过 .NET 中的 DataReader 通过 Load() 将数据读取到 DataTable?
有人对 DataTable.Load(DataReader) 方法有任何意见吗?
DataTable.Load 显示的行数少于源 DataReader