问题
There is a closely related question here: .NET DataTable skips rows on Load(DataReader)
I have a SQL Query that returns 169 results. The result looks like this:
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
This result is correct.
I entered the query in a C# program and execute it like this:
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;
}
This code is tested and it works fine for many different SQL queries.
But for the above query the DataTable
only contains 39 results and looks like this:
CustomerID Customer Name TerminalID Creation Date
1 First Customer 12347 2010-07-07
2 Second Customer 23456 2011-04-18
I fiddled around with the code a bit and here's what I found out so far: The FbDataReader
correctly fetches the results from the database. If I just query for the TerminalID
I end up with 169 results in the DataTable
. If I query for the CustomerID
I recieve 39 results.
Conclusion: The line result.Load(sqlReader)
groups the result for CustomerID
and throws away all other results, no matter if they can be grouped or not.
Why is this happening? How can I load the result of my query into the DataTable
without "losing" any rows due to unlogical grouping? And why does the DataTable
"group" the result in the first place?
Note: I also tried all three LoadOptions
available for DataTables
, all with the same outcome: Only 39 results are loaded into the DataTable
.
回答1:
Even if i don't know the problem i would suggest to use a DataAdapter
instead. Maybe that works:
// Get the results
using(var da = new FbDataAdapter(sqlCmd))
{
// Load the results into the table
da.Fill(result);
}
Why that happened? I think this answer in another question explains it.
回答2:
The DataTable.Load
method expects a primary key column in the underlying data (i.e. from DataReader
). Looks like your procedure does not have any primary key column, or if you have one please user order by
in the sql statement so that theDataTable
will able to accept it as primary.
This is an very old issue with DataTable.Load
and not very well documented. In general SQLDataAdapter
is good with DataTable
.
In your case, I think as soon as Load finds a duplicate it stops loading data. I have not get this documented anywhere but looks like this the issue.
回答3:
The soultion to the problem is as follows:
DataTable.Load()
looks for a Primary Key in the results. If the Primary Key it tries to load into the DataTable
already is present in that table, it overwrites the row with the new result.
However, using a different alias for the column with the Primary Key does solve the problem, all the results will get loaded into the DataTable
, since it seems the information that this column is a Primary Key is overwritten by using an alias.
来源:https://stackoverflow.com/questions/22663734/datatable-loadfbdatareader-does-not-load-everything-into-datatable