dbFactoryによる汎用的なDBアクセスで、ODP.NET独自のBindByNameプロパティを使う

dbFactory等のSystem.Data.Common名前空間のクラスにより、DBアクセスがプロバイダ非依存の形で記述できる。

だが残念なことに、この名前空間中のDbCommandクラスにはODP.NETにあるBindByNameプロパティがない!!

このプロパティを使うためだけにODP.NETを参照するのは本末転倒なので、以下にSystem.Data.Common.DbCommandを使ったままBindByNameプロパティを使うやり方を示す。
(System.Data,System.Data.Common,System.Reflectionの3つをusingする)

1.拡張メソッド用のstaticクラスをどこかに定義する。
2.staticメソッドSetBindByNameの中でリフレクションを使ってBindByNameプロパティにアクセス。
3.BindByNameプロパティが存在すれば値をセットする。

///


/// 拡張メソッド定義用Class
///

public static class ClassSatooExtentions {
///
/// OracleConnectionの場合に、BindByNameを使えるようにする
///

/// Oraclecommand
/// 名前つきBindするかどうか
public static void SetBindByName(this DbCommand command, bool isName) {
Type typeFileInfo = command.GetType();
PropertyInfo pi = typeFileInfo.GetProperty("BindByName");
if(pi != null) {
pi.SetValue(command, isName, null);
}
}
}

拡張メソッドで定義すると、使い方も非常に簡単に済む。
var command = con.CreateCommand();
command.SetBindByName(true);
これだけ。
実はSystem.Data.Common名前空間を使ってODP.NETを書き換えてる途中、BindByNameがないと気づいて、「ダメじゃん!」と思ったのが土曜日。
が、やはりOracleCommandではなくDbCommandでなんとかしたいなと思った。
一晩寝て日曜にGetSchema()あたりを調べてる途中閃いた!(^^)/

「そうだ!拡張メソッドとリフレクション使えばできるかも!」

で、書いたのが上のコード。できてしまえばあっけない...
ついでに引数ありのCreateParameter,CreateCommandなど、いくつか作ってみた。
拡張メソッドすごく便利!

  • 蛇足

なぜGetSchema()の途中で閃いたかというと...
実はGetSchema()で取得できるDataTable中のSQL文を使うと、Table一覧が取得できる。
しかしこのSQL文が、名前つきBindでないと実行できないようになってる(できなくはないが面倒...)
名前つきBindであれば、OWNERとTABLENAMEという名前の2つのパラメータを渡せばよいものを順番渡しだと、10個ぐらいにふくれあがるのだ。
昨日の時点では、「使えなければしょうがない」とあきらめたのだが、一度ならず2度までもBindByNameで引っかかってしまったんで、ちょっと本気で考えてみた...


(153624)