这里有一个密切相关的问题:.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
“将”结果放在第一位?
注意:我还尝试了LoadOptions
可用的所有三个DataTables
,结果相同:只有39个结果加载到DataTable
。
答案 0 :(得分:4)
即使我不知道问题,我建议改用DataAdapter
。也许这有效:
// Get the results
using(var da = new FbDataAdapter(sqlCmd))
{
// Load the results into the table
da.Fill(result);
}
为什么会这样?我认为this answer在另一个问题中解释了它。
答案 1 :(得分:3)
DataTable.Load
方法需要基础数据中的主键列(即来自DataReader
)。看起来您的过程没有任何主键列,或者如果您有一个请在sql语句中使用order by
,以便DataTable
能够接受它作为主要。
DataTable.Load
这是一个非常古老的问题,并没有很好的记录。一般情况SQLDataAdapter
适用于DataTable
。
在您的情况下,我认为只要Load找到重复,它就会停止加载数据。我没有在任何地方记录这些,但看起来像这个问题。
答案 2 :(得分:1)
问题的灵魂如下:
DataTable.Load()
在结果中查找主键。如果主键尝试加载到该表中已存在的DataTable
,它将用新结果覆盖该行。
但是,对于使用主键的列使用不同的别名确实可以解决问题,所有结果都会加载到DataTable
中,因为看起来此列的信息是使用别名覆盖主键。