web-dev-qa-db-ja.com

C#DbConnectionがSqlConnectionにキャストされました

このコードを1つのアプリケーションで見つけました

Database database = DatabaseFactory.CreateDatabase("connection string");
DbConnection connection = database.CreateConnection();
connection.Open();
SqlConnection sqlConnection = (SqlConnection)connection;

安全ですか、SqlConnectionはDbConnectionから派生します。データベースはMicrosoft.Practices.EnterpriseLibrary.Dataから取得されます。ドキュメントによると、CreteDatabaseはDbConnectionを返します。

19
Darqer

いいえ、それは安全ではありません。キャストは安全ではなく、アプリケーションの実行中にいつでもブローする可能性があります。 SqlConnectionは確かにDbConnectionから派生していますが、database.CreateConnection()SqlConnectionを返すことは保証されていません。これは構成ファイルでパラメーター化されている可能性があるためです。また、なぜSqlConnectionにキャストする必要があるのですか?コードを特定の実装と結合して、コードを単独でテストすることを不可能にすることを避けるために、階層の上位にあるクラスを操作することをお勧めします。

EnterpriseLibraryは物事を抽象的に保つのにまともな仕事をしていますが、あなたはこのキャストですべてを殺しています。また、使い捨てのリソースが常に適切に廃棄されていることを確認する必要があります。代わりにこれはどうですか:

Database database = DatabaseFactory.CreateDatabase("connection string");
using (var conn = database.CreateConnection())
using (var cmd = conn.CreateCommand())
{
    conn.Open();
    cmd.CommandText = "SELECT id FROM foo";
    using (var reader = cmd.ExecuteReader())
    {
        while (reader.Read())
        {
            // TODO: work with the results here
        }
    }
}

このようにして、コードは構成ファイル内のデータベースの変更に対して脆弱性が低くなります。もちろん、このSQLはまだハードコードされており、この状況を処理するORMがあります。また、SQLクエリの作成やデータベースプロバイダー間でのキャストに時間を費やす代わりに、アプリケーションの実際のドメインに集中できるようになります。しかし、単純なアプリケーションの場合はこれで問題ありません。

14
Darin Dimitrov

SQL Serverデータベース以外に接続するために接続文字列を変更しない限り、安全である必要があります。それが可能性がある場合は、物事を安全にするためにもう少しロジックを追加する必要があります。

Database database = DatabaseFactory.CreateDatabase("conn string");

using(DbConnection conn = database.CreateConnection())
{    
    if(conn is SqlConnection)
    {
        var sqlConn = conn as SqlConnection;
    }
}
11
Justin Niessner

これは、アプリケーションで使用しているデータベースによって異なります。あなたが書いたコードから、SQL Serverだけが使用されているように見えます。そうであれば、DbConnectionSqlConnectionに安全にキャストできます。実際、DbConnectionは他のデータベース接続の基本クラスです。あなたの場合、それはSqlConnectionSQL Serverデータベースでの作業に使用されます)です。また、OracleMysqlなどのさまざまなデータベースとそのプロバイダーもあります。通常、接続用の独自のクラスがあります。したがって、アプリが別のデータベースを使用する場合、または将来使用する可能性がある場合、そのようなキャストを行うことは危険です。

5
Andrew Bezzub

いつでもチェックを実行して、C#パターンマッチング(C#7.0 +)を使用してSqlConnectionに変換できます。

Database database = DatabaseFactory.CreateDatabase("conn string");

using(DbConnection connection = database.CreateConnection())
{    
    if(connection is SqlConnection sqlConnection)
    {
        // do something with sqlConnection
    }
    else
    {
       throw new InvalidOperationException("Connection is not to a SQL Database");
    }
}
1
Todd Skelton