博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

SqlHelper的几个细节

Posted on 2009-11-19 17:16  heeeey  阅读(180)  评论(0编辑  收藏  举报

最近研究了一下Microsoft的SqlHelper,设计的非常严谨,下面列一下几个细节的问题。

1. 判断是否由SqlHelper内部方法打开connection,如果是内部打开的话,需要在执行完SqlCommand的时候将其关闭。
   办法是在PrepareCommand中加入out bool mustcloseconnection,而在调用PrepareCommand方法中执行完SqlCommand后,将其关闭。
   我原来的做法只是在执行完SqlCommand后,一律关闭connection,这样的缺点是无法判断connection是否已由用户打开。
2。有的方法只传入了SqlTransaction,并没有相应的SqlConnection. 原因.对于只传入SqlTransaction的方法,可以通过SqlTransaction.Connection来找到SqlConnection,同时在由于SqlTransaction只能在SqlConnection打开的状态下才能赋值,所以我们可以认为connection已由用户在外部打开,因此执行完SqlCommand后不需要关闭SqlConnection.
3. 使用ExecuteReader(CommandBehavior.CloseConnection)返回SqlDataReader,则在SqlDataReader关闭的时候SqlConnection自动关闭。因此我们需要判断如果是由SqlHelper内部方法打开的,需要调用ExecuteReader(CommandBehavior.CloseConnection),如果是用户打开,调用ExecuteReader()
4. 使用deep copy 而不是 shadow copy,会出现 另一个 SqlParameterCollection 已包含带有 ParameterName“@UserName”的 SqlParameter。
      SqlParameter[] clonedParameters = new SqlParameter[originalParameters.Length];

   for (int i = 0, j = originalParameters.Length; i < j; i++)
   {
    clonedParameters[i] = (SqlParameter)((ICloneable)originalParameters[i]).Clone();
   }

   return clonedParameters;
5.  对于Connection,使用deep copy的情况
6.  使用SqlCommandBuilder.DeriveParameters(command)来得到存储过程的参数,同时由于DrivedParameters方法需要打开connection, 为了避免出现第一条的问题,采用Connection的deep copy
    SqlConnection clonedConnection = (SqlConnection)((ICloneable)connection).Clone()
    由于是deep copy,clonedConnection.State是默认值Closed.

DBHelper.cs