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 ,因为看起来该列是主键的信息会被使用别名覆盖。