前段时间在使用DAAB(Data Access Application Block) 2.0中的SqlHelper对象来做数据填充,因为2.0版本的SqlHelper里多了一个FillDataset方法很好使,特别是在你想使用存储过程一次性返回多个数据表时非常有用,它的一个重载方法中可以传入一个string[]类型的表名列表。但是在填充数据集的过程中,发现只要数据集中的表大于三张时老是会出问题,开始以为是自己的强类型数据集的字段类型或者字段个数与存储过程中取出的各个表的字段不一致,但是经过仔细检查并没有发现任何问题。这我就纳闷了,使用SqlHelper.FillDataset方法来填充三个表中的任意两个都没有问题,怎么多一个就出问题了?于是我把取出的结果集全部展开来看了一下,这才发现居然多了一个名为"Table2"的表,也就是说通过SqlHelper对象读出的表有四个,且第三个表被挤到了第四的位置,而且表三的内容居然也已经填充正确了,只不过表三的表名成了"Table2"!
我这下意识到应该是SqlHelper的问题了,于是我找到FillDataset的最后一个重载方法(SqlHelper.cs文件物理位置的最后一个):
private static void FillDataset(SqlConnection connection, SqlTransaction transaction, CommandType commandType,
string commandText, DataSet dataSet, string[] tableNames,
params SqlParameter[] commandParameters)
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
{
if( connection == null ) throw new ArgumentNullException( "connection" );
if( dataSet == null ) throw new ArgumentNullException( "dataSet" );
![](/Images/OutliningIndicators/InBlock.gif)
// Create a command and prepare it for execution
SqlCommand command = new SqlCommand();
bool mustCloseConnection = false;
PrepareCommand(command, connection, transaction, commandType, commandText, commandParameters, out mustCloseConnection );
// Create the DataAdapter & DataSet
using( SqlDataAdapter dataAdapter = new SqlDataAdapter(command) )
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
// Add the table mappings specified by the user
if (tableNames != null && tableNames.Length > 0)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
string tableName = "Table";
for (int index=0; index < tableNames.Length; index++)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
if( tableNames[index] == null || tableNames[index].Length == 0 ) throw new ArgumentException( "The tableNames parameter must contain a list of tables, a value was provided as null or empty string.", "tableNames" );
dataAdapter.TableMappings.Add(tableName, tableNames[index]);
tableName += (index + 1).ToString();
}
}
// Fill the DataSet using default values for DataTable names, etc
dataAdapter.Fill(dataSet);
![](/Images/OutliningIndicators/InBlock.gif)
// Detach the SqlParameters from the command object, so they can be used again
command.Parameters.Clear();
}
![](/Images/OutliningIndicators/InBlock.gif)
if( mustCloseConnection )
connection.Close();
}
请注意那段红色的语句:
tableName += (index + 1).ToString();
大家只要看一眼就明白了吧,这是一个很明显的bug! 当我们有两张表时,DataAdaper在做表名映射时就很正常,因为此时的两张表的tableName分别为Table和Table1, 但是再加上一张表或更多的话, 那tableName就成了Table12, Table123, Table1234, ...如此这般, 后果将不堪设想。怪不得我的结果数据集里面会多一张Table2出来,原来Table2根本就没有映射到我的强类型数据集的第三张表上来。
那么既然发现了bug,我们就得手工改正一下了,其实很简单,只需要将那段语句改为:
tableName = "Table" + (index + 1).ToString();
这样就一切OK了。
不知道MS现在是否已经修复了DAAB2.0里的这个bug,但至少我上个月才下载的这个版本里还存在有。