我写了一个方法,它从IDataReader
源(使用yield
关键字)获取后立即返回DataRow
。它可以工作,但它的确比使用SqlDataAdapter
填充DataTable
慢。如何使用SqlDataReader像使用SqlDataAdapter一样快地填充DataTable?
public static IEnumerable<DataRow> AsEnumerable(this IDataReader source)
{
//create columns
DataTable dt = new DataTable();
for (int i = 0; i < source.FieldCount; i++)
{
dt.Columns.Add(source.GetName(i), source.GetFieldType(i));
}
//fetch data
object[] data = new object[source.FieldCount];
dt.BeginLoadData();
while (source.Read())
{
DataRow dr = dt.NewRow(); //this is very slow, bottleneck ?
source.GetValues(data);
for (int i = 0; i < source.FieldCount; i++)
{
dr[i] = data[i];
}
dt.Rows.Add(dr);
yield return dr;
}
dt.EndLoadData();
}
下面是结果(250.000行,许多列):
00:08:34.652 //using SqlDataAdapter
00:12:95.153 //using method above
我怎样才能使它尽可能快地使用SqlDataAdapter
?
为什么我使用这个而不是SqlDataAdapter
:我想尽快处理来自源头的行,而不是“阻塞”很长时间,并等待所有记录在那里。
也许有另一种方法来做到这一点。注:我不能简单地产生一个IDataReader
(这是快速和支持我所需要的:使用Item[ColumnName]
访问数据,因为数据将由不同的线程加入,所以我需要在移动到下一行之前将它复制到某处...
也许它会更快,只是做source.GetData(dr.ItemArray); –
好的建议。我要试试这个。我在提出这个问题之前所尝试的是使用DataRow.ItemArray [i](内部for循环)填充DataRow,它非常慢。 – tigrou
它稍微快一点,我得到9.6和10.5秒(好),但它仍然总是比SqlDataAdapter慢(即使几次尝试后) – tigrou