一聚教程网:一个值得你收藏的教程网站

最新下载

热门教程

asp.net中大数据导致DataReader.Close超时的异常

时间:2013-09-30 编辑:简简单单 来源:一聚教程网


因海关业务复杂,数据量极大,在做sql自定义查询的时候需要限定返回结果集DataSet的数据量,微软本身的DataAdpter的Fill方法根本无法满足其需要,所以得自己想法实现,再自己实现了IDataReader转换为DataSet的方法后,发现在调用DataReader.Close的时候老是报“超时异常”。仔细翻阅了MSDN对Close方法的说明后,在备注的地方发现了这么一段话:

Close 方法填写输出参数的值、返回值和 RecordsAffected,从而增加了关闭用于处理大型或复杂查询的 SqlDataReader 所用的时间。如果返回值和查询影响的记录的数量不重要,则可以在调用 Close 方法前调用关联的 SqlCommand 对象的 Cancel 方法,从而减少关闭 SqlDataReader 所需的时间。

DataReader为了计算RecordsAffected值,在Close之前会继续读取剩下的记录,直到读完为止。原来执行Command的Cancel方法就可以解决这个问题。

下面是我的测试函数代码(仅供参考):

 代码如下 复制代码


public static void FillDataSet2(DataSet ds, DbCommand cmd, int pageSize, int pageIndex)
{
DataTable table = new DataTable();
using (IDataReader reader = cmd.ExecuteReader(CommandBehavior.CloseConnection))
{
int fieldCount = reader.FieldCount;
for (int i = 0; i < fieldCount; i++)
{
table.Columns.Add(reader.GetName(i), reader.GetFieldType(i));
}
ds.Tables.Add(table);
object[] values = new object[fieldCount];
int currentIndex = 0;
int startIndex = pageSize * pageIndex;
try
{
table.BeginLoadData();
while (reader.Read())
{
if (startIndex > currentIndex++)
continue;
if (pageSize > 0 && (currentIndex – startIndex) > pageSize)
break;
reader.GetValues(values);
table.LoadDataRow(values, true);
}
}
finally
{
table.EndLoadData();
//注意调用Cancel()方法:读取一半的时候调用SqlDataReader.Close()来关闭读取.结果老是提示操作超时。
//Msdn解释:
//Close 方法填写输出参数的值、返回值和 RecordsAffected,从而增加了关闭用于处理大型或复杂查询的 SqlDataReader 所用的时间。
//如果返回值和查询影响的记录的数量不重要,则可以在调用 Close 方法前调用关联的 SqlCommand 对象的 Cancel 方法,从而减少关闭 SqlDataReader 所需的时间。
cmd.Cancel();
reader.Close();
}
}
}
 

解决问题,效率也还可以。

注:之所以不用实体和高效率的分页方法,是因为sql语句为业务人员自己写的,无法确定有哪些字段,语句复杂度也无法确定,所以采用此方法。

热门栏目