这个让我难过。以下是代码的相对位:
public AgencyDetails(Guid AgencyId)
{
try
{
evgStoredProcedure Procedure = new evgStoredProcedure();
Hashtable commandParameters = new Hashtable();
commandParameters.Add("@AgencyId", AgencyId);
SqlDataReader AppReader = Procedure.ExecuteReaderProcedure("evg_getAgencyDetails", commandParameters);
commandParameters.Clear();
//The following line is where the error is thrown. Errormessage: Invalid attempt to call Read when reader is closed.
while (AppReader.Read())
{
AgencyName = AppReader.GetOrdinal("AgencyName").ToString();
AgencyAddress = AppReader.GetOrdinal("AgencyAddress").ToString();
AgencyCity = AppReader.GetOrdinal("AgencyCity").ToString();
AgencyState = AppReader.GetOrdinal("AgencyState").ToString();
AgencyZip = AppReader.GetOrdinal("AgencyZip").ToString();
AgencyPhone = AppReader.GetOrdinal("AgencyPhone").ToString();
AgencyFax = AppReader.GetOrdinal("AgencyFax").ToString();
}
AppReader.Close();
AppReader.Dispose();
}
catch (Exception ex)
{
throw new Exception("AgencyDetails Constructor: " + ex.Message.ToString());
}
}
执行ExecuteReaderProcedure:
public SqlDataReader ExecuteReaderProcedure(string ProcedureName, Hashtable Parameters)
{
SqlDataReader returnReader;
using (SqlConnection conn = new SqlConnection(connectionString))
{
try
{
SqlCommand cmd = new SqlCommand(ProcedureName, conn);
SqlParameter param = new SqlParameter();
cmd.CommandType = System.Data.CommandType.StoredProcedure;
foreach (DictionaryEntry keyValue in Parameters)
{
cmd.Parameters.AddWithValue(keyValue.Key.ToString(), keyValue.Value);
}
conn.Open();
returnReader = cmd.ExecuteReader(CommandBehavior.CloseConnection);
}
catch (SqlException e)
{
throw new Exception(e.Message.ToString());
}
}
return returnReader;
}
连接字符串正在运行,因为同一个类中的其他存储过程运行正常。唯一的问题似乎是从这个方法返回SqlDataReaders!他们在标题中抛出错误消息。任何想法都非常感谢!提前谢谢!
答案 0 :(得分:5)
DataReader
通常直接连接到数据库。在这种情况下,当您从方法返回时,您将从创建using
对象的SqlConnetion
语句内部返回。这会在Dispose
上调用SqlConnection
,并使SqlDataReader
无用。
试试这个:
public SqlDataReader ExecuteReaderProcedure(string ProcedureName, Hashtable Parameters)
{
SqlConnection conn = new SqlConnection(connectionString);
using(SqlCommand cmd = new SqlCommand(ProcedureName, conn))
{
cmd.CommandType = System.Data.CommandType.StoredProcedure;
foreach(DictionaryEntry keyValue in Parameters)
{
cmd.Parameters.AddWithValue(keyValue.Key.ToString(), keyValue.Value);
}
conn.Open();
return cmd.ExecuteReader(CommandBehavior.CloseConnection);
}
}
这样称呼:
public AgencyDetails(Guid AgencyId)
{
evgStoredProcedure Procedure = new evgStoredProcedure();
Hashtable commandParameters = new Hashtable();
commandParameters.Add("@AgencyId", AgencyId);
using(SqlDataReader AppReader =
Procedure.ExecuteReaderProcedure("evg_getAgencyDetails",
commandParameters))
{
commandParameters.Clear();
while(AppReader.Read())
{
AgencyName = AppReader.GetOrdinal("AgencyName").ToString();
AgencyAddress = AppReader.GetOrdinal("AgencyAddress").ToString();
AgencyCity = AppReader.GetOrdinal("AgencyCity").ToString();
AgencyState = AppReader.GetOrdinal("AgencyState").ToString();
AgencyZip = AppReader.GetOrdinal("AgencyZip").ToString();
AgencyPhone = AppReader.GetOrdinal("AgencyPhone").ToString();
AgencyFax = AppReader.GetOrdinal("AgencyFax").ToString();
}
}
}
在using
的{{1}}语句末尾,将调用AppReader
。由于您使用AppReader.Dispose
来呼叫ExecuteReader
,因此处理读取器也会关闭连接。
请注意,我也摆脱了您的错误异常处理。除了可能向最终用户显示外,切勿使用CommandBehavior.CloseConnection
。其他人都想要完整的例外。此外,如果允许传播完整的异常,则无需将方法名称作为异常消息的一部分进行打印。方法名称将位于堆栈跟踪中。