このコードを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を返します。
いいえ、それは安全ではありません。キャストは安全ではなく、アプリケーションの実行中にいつでもブローする可能性があります。 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クエリの作成やデータベースプロバイダー間でのキャストに時間を費やす代わりに、アプリケーションの実際のドメインに集中できるようになります。しかし、単純なアプリケーションの場合はこれで問題ありません。
SQL Serverデータベース以外に接続するために接続文字列を変更しない限り、安全である必要があります。それが可能性がある場合は、物事を安全にするためにもう少しロジックを追加する必要があります。
Database database = DatabaseFactory.CreateDatabase("conn string");
using(DbConnection conn = database.CreateConnection())
{
if(conn is SqlConnection)
{
var sqlConn = conn as SqlConnection;
}
}
これは、アプリケーションで使用しているデータベースによって異なります。あなたが書いたコードから、SQL Serverだけが使用されているように見えます。そうであれば、DbConnection
をSqlConnection
に安全にキャストできます。実際、DbConnection
は他のデータベース接続の基本クラスです。あなたの場合、それはSqlConnection
(SQL Server
データベースでの作業に使用されます)です。また、Oracle
、Mysql
などのさまざまなデータベースとそのプロバイダーもあります。通常、接続用の独自のクラスがあります。したがって、アプリが別のデータベースを使用する場合、または将来使用する可能性がある場合、そのようなキャストを行うことは危険です。
いつでもチェックを実行して、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");
}
}