在DAL中处理数据库连接的最佳方法 - 创建还是通过?

mag*_*tic 5 c# asp.net connection data-access-layer

我希望我的数据访问层可以非常模块化地构建.
因此,我有数据检索方法,有时直接从业务层调用,有时由其他数据检索方法调用以创建对象依赖项.

在DAL中处理数据库连接的最佳方法是什么?

a)在每个方法中创建一个新连接,然后再处理它.
好:易于编写和使用.
坏:许多连接正在打开和关闭.(性能?)

b)将连接作为(可选)参数传递.
好:我可以为多个命令重用开放连接.
不好:我必须跟踪连接的所有权(谁必须关闭它?)并且不能使用非常简洁的"使用"语句.

c)还有别的吗?(单身连接可能?)

这是我第一次写一个真正的DAL,所以我真的可以从经验丰富的人那里得到一些帮助.

编辑:因为它似乎很重要,它是一个ASP.Net网站项目.

Nic*_*rey 4

如果您使用 ASP.Net,那么选项 A 是您的最佳选择。

为每个请求创建一个新连接,请求完成后进行 Dispose()。确保使用相同的连接字符串。连接将(默认情况下)保持打开状态并通过连接池可用。

有关连接池的详细信息,请参阅http://msdn.microsoft.com/en-us/library/8xx3tyca.aspx 。

您几乎必须在网络服务器中这样做,这样就不会出现并发问题。一切都需要是线程安全的(您不知道应用程序中正在执行多少个并发工作线程)。

[编辑添加示例代码]

作为示例,以下是我认为执行存储过程的典型方法。这来自我编写的自定义代码生成器 - 手写代码可能看起来有点不同 - 但它应该足以阐明要点:

public int Exec(  int? @iPatientID )
{
  using ( SqlConnection  conn = new SqlConnection( this.ConnectString ) )
  using ( SqlCommand     cmd  = conn.CreateCommand() )
  using ( SqlDataAdapter sda  = new SqlDataAdapter( cmd ) )
  {
    cmd.CommandText = STORED_PROCEDURE_NAME ;
    cmd.CommandType = CommandType.StoredProcedure ;

    if ( this.TimeoutInSeconds.HasValue )
    {
      cmd.CommandTimeout = this.TimeoutInSeconds.Value ;
    }

    //
    // 1. @iPatientID
    //
    SqlParameter p1 = new SqlParameter( @"@iPatientID" , SqlDbType.Int ) ;
    if ( @iPatientID == null )
    {
      p1.Value = System.DBNull.Value ;
    }
    else
    {
      p1.Value = @iPatientID ;
    }
    cmd.Parameters.Add( p1 ) ;

    // add return code parameter
    SqlParameter pReturnCode = new SqlParameter() ;
    pReturnCode.SqlDbType    = System.Data.SqlDbType.Int ;
    pReturnCode.Direction    = System.Data.ParameterDirection.ReturnValue ;
    cmd.Parameters.Add( pReturnCode ) ;

    DataSet ds = new DataSet() ;

    conn.Open() ;
    sda.Fill( ds ) ;
    conn.Close() ;

    this.ResultSet  = ( ds.Tables.Count > 0 ? ds.Tables[0] : null ) ;
    this.ReturnCode = (int) pReturnCode.Value ;

  }

  return this.ReturnCode ;

}
Run Code Online (Sandbox Code Playgroud)