DataTable.Load(FbDataReader)不会将所有内容加载到DataTable中
这里有一个密切相关的问题: .NET DataTable在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
。 也许这有效:
// Get the results using(var da = new FbDataAdapter(sqlCmd)) { // Load the results into the table da.Fill(result); }
为什么会这样? 我认为另一个问题的答案解释了这一点。
DataTable.Load
方法需要底层数据中的主键列(即来自DataReader
)。 看起来您的过程没有任何主键列,或者如果您在sql语句中有一个请用户order by
以便DataTable
能够接受它作为主要。
这是DataTable.Load
一个非常古老的问题,并没有很好的记录。 通常, SQLDataAdapter
适用于DataTable
。
在您的情况下,我认为一旦Load找到重复,它就会停止加载数据。 我没有在任何地方记录这些,但看起来像这个问题。
问题的灵魂如下:
DataTable.Load()
在结果中查找主键 。 如果它尝试加载到DataTable
的主键已经存在于该表中,它将用新结果覆盖该行。
但是,对具有主键的列使用不同的别名确实可以解决问题,所有结果都将加载到DataTable
,因为看起来该列是主键的信息会被使用别名覆盖。