我正在查看一个有点旧的应用程序的冗长数据访问代码。每个函数都调用一个存储过程来从Oracle DB中选择一些东西。每个函数或多或少看起来像下面的代码:
public List<SomeObject> GetMeSomethingFromDB(string myParam, int anotherParam)
{
OracleConnection conn = null;
OracleDataReader dataReader = null;
try
{
conn = new OracleConnection(Settings.ConnectionString);
conn.Open();
var cmd = new OracleCommand("STORED_PROC_NAME", conn);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add(new OracleParameter("IN_MY_PARAM", OracleDbType.Varchar2)).Value = myParam;
cmd.Parameters.Add(new OracleParameter("IN_ANOTHER_PARAM", OracleDbType.Int32)).Value = anotherParam;
cmd.Parameters.Add(new OracleParameter("OUT_REF_CURSOR", OracleDbType.RefCursor)).Direction = ParameterDirection.Output;
dataReader = cmd.ExecuteReader();
List<SomeObject> result = new List<SomeObject>();
if (dataReader == null || !dataReader.HasRows) return result;
while (dataReader.Read())
{
SomeObject someObject = new SomeObject
{
SomeId = (int)dataReader["SOME_ID"],
SomeStringValue = dataReader["SOME_STRING_VALUE"].ToString()
};
result.Add(someObject);
}
return result;
}
catch (Exception e)
{
throw e;
}
finally
{
if (dataReader != null)
{
dataReader.Close();
dataReader.Dispose();
}
if (conn != null)
{
if (conn.State == ConnectionState.Open) conn.Close();
conn.Dispose();
}
}
}
我的问题是:
1.某些函数使用类级别的OracleConnection变量。函数级别还是类级别的变量是首选?
1.检查dataReader == null
是必要的吗?在cmd.ExecuteReader()
调用之后它会是NULL吗?
1.当涉及到连接Close/Dispose和读卡器Close/Dispose时,功能有所不同。关闭/Dispose的正确方式/顺序是什么?如果连接被释放,读卡器不会自动关闭/Dispose吗?
1.我希望在不久的将来将Oracle.ManagedDataAccess.Client连接到该项目。此代码中的任何更改都将与托管数据访问客户端一起使用吗?
1条答案
按热度按时间biswetbf1#
using statement将大大简化您的代码。
1.始终使用本地连接对象,并将其包含在using语句中,以便正确关闭和处置该对象(OracleDataReader和OracleCommand也是如此)。这将从保持与代码的连接所需的内存和线程中释放服务器,并且性能由ADO.NET提供程序启用的connection pooling保证
1.不需要,如果您计划循环结果,则不需要调用,也不需要调用 HasRows。如果没有行或到达数据集的末尾,读取器将返回false
1.看看using语句的要点。正确的using语句会把这个问题从你的负担中去除。
1.如果您使用Oracle的ODP提供程序,则此代码不会有任何问题
1.如果你只想重新抛出异常,就不需要try catch。只要让它冒泡到上层,而不使用
throw e
中断堆栈跟踪,finally语句中所需的所有代码都由编译器隐式添加到using右花括号中。