3

バックグラウンド:

私は再利用のために ac# 4.0 クラスを作成しているので、プログラムのほとんどのメソッドに 1 つのパラメーターを送信し、次のようなものを保持できる「接続」オブジェクトを渡すことができます。

  • 接続文字列
  • DbConnection (つまり、OleDbConnection または SQLConnection)
  • DataReader (つまり、OleDbDataReader または SQLDataReader)

その理由は、最終的に SQL Server にアップグレードする予定であり、メソッドのパラメーターやコードをあまり変更したくないからです。メソッドは、多くの場合、同じデータベースからあちこちでクイック クエリを呼び出さなければなりません。

質問:

以下の行のメソッドで、DbType の DRMDbConnection 'set' パラメータ (現在は整数 1 としてハードコードされています) の右側を適切にセットアップ (および呼び出し) するにはどうすればよいですか。

set { drmDbConnection = SetDRMDbConnection(1); }

サンプルコード:

public class Connections
{

public string DRMDbConnectionString { get; set; }
private object drmDbConnection;

public object DRMDbConnection
{
  get { return drmDbConnection; }
  set { drmDbConnection = SetDRMDbConnection(1); }
}

private object SetDRMDbConnection(int DbType)
{
  if (DbType == 1)
    return new System.Data.OleDb.OleDbConnection();
  else
    return new SqlConnection();
}

}

10月31日編集

推奨される IDbConnection、IDbCommand、および IDataReader を使用するようにクラス コードを更新しました。注: SQL Server 接続文字列を変更しないと、次のエラーが表示されます。したがって、これを接続文字列に追加します: "MultipleActiveResultSets=True;"

更新されたクラス コード

public class Connections
// reusuable object to hold all database Connections and a convenient DataReader and Command object.
// Its purpose is to also be able to handle your choice of database connection, i.e. OleDb or SQL Server.
{
public string DRMConnectionString { get; set; }
public IDbConnection DRMConnection;

public IDbCommand DRMCommand
{
  get { return DRMConnection.CreateCommand(); }
  set { }
}

public int DRMConnectionType
// must be called to setup database connection and command.  The connectionstring must be previously set.
{
  set
  {
    if (value == 1)
      DRMConnection = new System.Data.OleDb.OleDbConnection(DRMConnectionString);
    else
      DRMConnection = new SqlConnection(DRMConnectionString);
  }
}

public void CloseConnections()
{
  if (DRMCommand != null)
    DRMCommand.Dispose();

  if ((DRMConnection != null) && (DRMConnection.State != ConnectionState.Closed))
    DRMConnection.Close();
}
}

コーリングコード

var conn = new Connections();
conn.DRMConnectionString = "my connection string";
conn.DRMConnectionType = 2;
conn.DRMConnection.Open();
try
{
  using (var cmd = conn.DRMCommand)
  {
    cmd.CommandText = "SELECT * FROM MyTable";
    using (var rdr = cmd.ExecuteReader())
    {
      while (rdr.Read())      
      {
         CallSubMethodThatAlsoOpensDataReader(conn);  
      } 
    } 
  }
}
finally
{
  conn.CloseConnections();
} 


CallSubMethodThatAlsoOpensDataReader(Connections Conn)
{
  using (var cmd = Conn.DRMCommand)
  {
    cmd.CommandText = "SELECT * FROM MyOtherTable";
    using (var rdr = cmd.ExecuteReader())  // Error: There is already an open DataReader associated with this Command which must be closed first.
    {
       ; // do stuff
    } 
  }
}
4

2 に答える 2

1

プロパティの getter/setter はパラメータを取ることができません。これをメソッドとして実装する必要があります。

于 2012-10-26T19:13:46.200 に答える
1

次のように動作させることができます。

public IDbConnection DRMDbConnection // Note the change of the type
{
    get { return drmDbConnection; }
}
public int DrmDbConnectionType
{
    set {
        if (vale== 1)
            drmDbConnection = new System.Data.OleDb.OleDbConnection();
        else
            drmDbConnection = new SqlConnection();
    }
}

その理由は、最終的に SQL Server にアップグレードする予定であり、メソッドのパラメーターやコードをあまり変更したくないからです。

これがあなたが解決しようとしている重要な問題だと思います。特定のクラスに対してプログラミングするのではなく、インターフェイスに対してプログラミングします。具体的には、 orIDbConnectionの代わりに使用すると、 にカプセル化するよりも正確な型を隠すことができます。SqlConnectionOleDbConnectionDRMDbConnection

于 2012-10-26T19:18:08.927 に答える