2016-11-18 1 views
1

SQL DBロジックにIDbCommandおよびIDbDataParameterインターフェイスを使用していますが、インターフェイスの制約のためにsqlCommand.parameter["ID"] .Valueを取得できないことに気付きました。TypeCastインターフェイス制限を克服するには?

インターフェイスの制限を克服するために、インターフェイスオブジェクトをタイプキャストすることをお勧めしますか?

using (IDbCommand SqlCmd = CommandProvider.GetSPCommand(conn)) 
{ 
    // setup sqlcmd with output paramter and executenonquery ... 
    ID = Convert.ToInt32(((SqlCommand)SqlCmd).Parameters["ID"].Value); 
} 
+0

一般に、インタフェースが公開していないことを行う必要がある場合は、間違ったインタフェースを使用しています。 GetSPCommand()によって返される型は何ですか? – David

+0

戻り値の型はSqlCommand – Ralph

+1

です。その場合は、まずインターフェイスを使用して何も得られません。変数型として 'SqlCommand'を使うだけです。 – David

答えて

3

いいえ、これは良い習慣ではありません。

最初に、が絶対にでなければ、ダウンキャストしないでください。インターフェイス実装によってのみ提供される値が必要な場合は、その実装から開始します。 CommandProvider.GetSPCommandは、SqlCommandオブジェクトを返した場合、あなたのケースで、そしてちょうど行います

using (SqlCommand SqlCmd = CommandProvider.GetSPCommand(conn)) 
{ 
    // setup sqlcmd with output paramter and executenonquery ... 
    ID = Convert.ToInt32(((SqlCommand)SqlCmd).Parameters["ID"].Value); 
} 

それは、あなたがチェックする前にキャストをしているあなたは間違って持っている二つ目に実行した、ことを行わない場合それが安全であれば。返品された商品でない場合、SqlCommandのコードはInvalidCastExceptionとなります。唯一の好ましい選択肢であるインタフェースを使用して、もちろん

using (IDbCommand SqlCmd = CommandProvider.GetSPCommand(conn)) 
{ 
    SqlCommand fullSqlCommand = SqlCmd as SqlCommand; 
    if (fullSqlCommand != null) 
    { 
     // setup sqlcmd with output paramter and executenonquery ... 
     ID = Convert.ToInt32(fullSqlCommand.Parameters["ID"].Value); 
    } 
    else 
    { 
     //Some failsafe 
    } 
} 

が、この場合のように、あなたはそれをコントロールしていないとき、それは難しいことができます。その代わり、asオペレータに確認してください。

+0

あなたの助けに感謝します。それは私の問題を明確にするのに役立ちます。私はIDbCommandインターフェイスではなくSqlCommandで宣言しなければならないと思います。 – Ralph

0

ブラッドリーは正確であり、彼の答えと簡潔です。私はまた、あなたのコードに基づいて、ストアドプロシージャのパラメータにアクセスすることは、必ずしも特定の実装に結合する要素である必要はありません追加します。 データベースに依存しないデータアクセスコードを達成するための私の好きなツールの一つは、Dapperの素晴らしい魔法です。信じられないかもしれませんが、それはスタックオーバーフローを実行するデータアクセスライブラリです!そのdocumentationから

、あなたはこのコードを追加して、アクセスパラメータができます。

var p = new DynamicParameters(); 
p.Add("@a", 11); 
p.Add("@b", dbType: DbType.Int32, direction: ParameterDirection.Output); 
p.Add("@c", dbType: DbType.Int32, direction: ParameterDirection.ReturnValue); 

cnn.Execute("spMagicProc", p, commandType: CommandType.StoredProcedure); 

int b = p.Get<int>("@b"); 
int c = p.Get<int>("@c"); 

あなたは、その後などのIDbCommand、のIDbConnection、のような抽象化に対してコーディング保つことができるDapperのは、から値を取っての非常にパフォーマンスの方法を持っていますデータベースを簡単にC#タイプに変換することができます(これにより、いくつかの領域にキャストする必要がなくなる可能性があります)。

ハードキャスト(parenthesesを使用)またはソフトキャストによるキャスティングは、少なくとも私の本では、両方ともコードの匂いと考えられています(私はブラッドリーと同意しますが、必要ならばソフトになります)。いくつかの特定の分野でのみ、絶対にそれを行う必要があります。簡単なアプリケーションの場合、データベースに完全に依存して、気楽にお気軽にお気軽に。重要ではないエンタープライズアプリケーションでは、データベースに強く依存すると、最終的にアプリケーションスタックをベンダーロックし、将来のリファクタリングを危険にさらします。

関連する問題