如果 DataReader 返回两个结果集,则使用 DataTable.Load() 方法不起作用
Using DataTable.Load() method is not working in case two resultsets returned by DataReader
出于提高性能的动机,我试图消除数据集的使用并实施 DataReader。这里我的 Oracle 过程返回两个 refcursors & 当我将第一个记录集加载到第一个 DataTable 时,下一个永远不会加载。
示例代码如下所示:
DataSet ds = new DataSet();
using (OracleConnection db = new OracleConnection(conString))
{
try
{
using (OracleCommand mycom = new OracleCommand())
{
mycom.CommandText = "myPkg.pr_mySP";
mycom.Connection = db;
mycom.CommandType = CommandType.StoredProcedure;
mycom.Parameters.Add("ref_list1", OracleDbType.RefCursor).Direction = ParameterDirection.Output;
mycom.Parameters.Add("ref_list2", OracleDbType.RefCursor).Direction = ParameterDirection.Output;
//mycom.FetchSize = mycom.FetchSize * 64;
db.Open();
using (OracleDataReader reader = mycom.ExecuteReader())
{
DataTable custMapList = new DataTable("dtcustMapList");
custMapList.Load(reader);
reader.NextResult(); // POST THIS THE SECOND DATATABLE DOESNOT GETTING POPULATED
DataTable custMapSubList = new DataTable("dtcustMapSubList");
custMapSubList.Load(reader);
ds.Tables.Add(custMapList);
ds.Tables.Add(custMapSubList);
}
}
}
catch (Exception ex)
{
returnString += "Error, " + ex.Message;
}
我知道有其他方法,比如循环使用 while(reader.Read()) ... & 然后使用 reader.NextResult() 会起作用,但在那种情况下我必须改变许多其他方法如果上述工作正常,我认为可以避免的代码。
感谢您尽早回复。
查看 reference source 的 DataTable.Load
方法,很明显该方法在退出前调用 NextResult()
,因此您不需要这样做。
....
if(!reader.IsClosed && !reader.NextResult())
reader.Close();
....
顺便说一句,没有必要去源头。 MSDN 还说:
The Load method consumes the first result set from the loaded
IDataReader, and after successful completion, sets the reader's
position to the next result set, if any.
所以你只需要删除这一行
// reader.NextResult(); // POST THIS THE SECOND DATATABLE DOESNOT GETTING POPULATED
出于提高性能的动机,我试图消除数据集的使用并实施 DataReader。这里我的 Oracle 过程返回两个 refcursors & 当我将第一个记录集加载到第一个 DataTable 时,下一个永远不会加载。
示例代码如下所示:
DataSet ds = new DataSet();
using (OracleConnection db = new OracleConnection(conString))
{
try
{
using (OracleCommand mycom = new OracleCommand())
{
mycom.CommandText = "myPkg.pr_mySP";
mycom.Connection = db;
mycom.CommandType = CommandType.StoredProcedure;
mycom.Parameters.Add("ref_list1", OracleDbType.RefCursor).Direction = ParameterDirection.Output;
mycom.Parameters.Add("ref_list2", OracleDbType.RefCursor).Direction = ParameterDirection.Output;
//mycom.FetchSize = mycom.FetchSize * 64;
db.Open();
using (OracleDataReader reader = mycom.ExecuteReader())
{
DataTable custMapList = new DataTable("dtcustMapList");
custMapList.Load(reader);
reader.NextResult(); // POST THIS THE SECOND DATATABLE DOESNOT GETTING POPULATED
DataTable custMapSubList = new DataTable("dtcustMapSubList");
custMapSubList.Load(reader);
ds.Tables.Add(custMapList);
ds.Tables.Add(custMapSubList);
}
}
}
catch (Exception ex)
{
returnString += "Error, " + ex.Message;
}
我知道有其他方法,比如循环使用 while(reader.Read()) ... & 然后使用 reader.NextResult() 会起作用,但在那种情况下我必须改变许多其他方法如果上述工作正常,我认为可以避免的代码。
感谢您尽早回复。
查看 reference source 的 DataTable.Load
方法,很明显该方法在退出前调用 NextResult()
,因此您不需要这样做。
....
if(!reader.IsClosed && !reader.NextResult())
reader.Close();
....
顺便说一句,没有必要去源头。 MSDN 还说:
The Load method consumes the first result set from the loaded IDataReader, and after successful completion, sets the reader's position to the next result set, if any.
所以你只需要删除这一行
// reader.NextResult(); // POST THIS THE SECOND DATATABLE DOESNOT GETTING POPULATED