昨日のGlimpseネタの続き(?)です。
Glimpseには公式・非公式(?)にいくつものExtensionsが提供されていて、その中の一つがGlimpse.Adoです。
Glimpse.Adoはその名の通り、ADO.NETをトレースするエクステンションです。生ADOやDataSetを使ったDBアクセスのトレースを行えます。Glimpseのチームにより提供されているようで、公式(?)エクステンションといってもいいのかもしれません。
なお、Entity Frameworkを使っている場合はGlimpse.EF43、Glimpse.EF5、Glimpse.EF6とそれぞれのバージョン用が提供されていますので、EF使われている方はそちらをどうぞ。
以下に、ざっくりとした利用方法と実行例をご紹介してみたいと思います。
※追記・訂正あり
利用方法
導入方法はGlimpse本体と同じく、NuGetでの導入になります。またその前に、選択したASP.NETのフレームワークに合ったGlimpse(Glimpse.Mvc*やGlimpse.WebForms)を導入しておく必要があります。
また、実際にADOのトレースを行うにはコーディング時に専用の記述を行う必要がある点も注意してください。
インストール
コマンドラインの場合は
Install-Package Glimpse.Ado
GUIの場合は以下のように検索してインストールしてください。
コーディング時の注意
普通に書くだけではトレースできない
Glimpse.Adoでトレースを行う場合、実はそのままADO.NETでDBアクセス処理を実行してもトレースが行われません。 専用のコネクションオブジェクトを利用する必要があります。
通常、ADO.NETでDBにアクセスする場合はこんな感じで書くと思います。 通常のADO.NETの例
が、これだとGlimpse.Adoではトレースできません。
トレースするためにGlimpseDbConnectionを利用する
GlimpseでADO.NETの状況をトレースするためには、DbConnectionとしてGlimpse.Adoが提供するGlimpseDbConnectionを利用する必要があるようです。 以下のように元のDbConnectionオブジェクトをGlimpseDbConnectionのコンストラクタに渡してやるとトレースを取得することが出来ました。 Glimpse.Adoを利用する場合の例
なお、上記の場合はコネクションオブジェクトを差し替えるだけですが、System.Data.SqlClientやSystem.Data.SqlServerCe独自のメンバ/型を使っていると利用できない場合があるようです。例えば、パラメータオブジェクトのSqlDbType(System.Data.SqlDbType)を利用するコードになっている場合、これはSystem.Data.Common.- のクラスには存在しないメンバである為、そのまま差し替えはできません。
【追記アリ・後述します】
実行とトレース
無事に実行できると、GlimpseのSQLタブで以下のようなトレース情報を取得することができます(画像クリックで拡大(するハズ))。
実行したコマンドや実際にバインドされたパラメータなども確認できるので、ものすごく便利です!
利用できるDBプロバイダに制限があるので注意
しかし、このGlimpse.Adoでトレースできるのは、今のところSQL ServerとSQL Server CEのみのようです。Oracleでこれが出来ると個人的にとても助かるんですが…(^^;
【訂正・Oracleでもできました。詳しくは後述】
ともあれ、SQL Server/ SQL Server CEを生ADO.NETで利用する場合は強力な武器になると思いますので、ご利用を検討されると良いのではないかと思います。
追記・Oracle(ODP.NET)での対応について
訂正です。Oracle(ODP.NET)でもトレースができることを確認しました。
NGだったパターン
『使えなかった』と判断したのは、上記のSQL Server CE の例と同様、ODPのConnectionオブジェクトをGlimpseDbConnectionに食わせてたやったパターン。例えば下記のような感じです。 ODP.NETでGlimpse.Ado NGのパターン
こうすると、こんな例外が出るんですね。
Glimpse requires that we can find the underlying DbProviderFactory from within your connection. Your current connection of type 'Oracle.DataAccess.Client.OracleConnection' does not support this functionality. If you control the implementation, changing this so we can support you shouldn't be that difficult.
このため、これでてっきりOracleは完全にサポート外だとあきらめかけていました。
OKなパターン
が、@neueccさんが「MySQLでは行けてますよん」とツッコミをくださったので、もしやと思い、スタックトレースに頼りにちらっとソースを追いかけつつ、ピンと来たので試してみたところ…うまくいきました。
結果的にいうと、SQL Server系の場合は問題なかったようですがODPでは直接GlimpseDbConnectionに食わせてもだめで、以下のようにDbProviderFactory経由でConnectionオブジェクトのインスタンスを作ってやる必要があったようです。 ODP.NETでGlimpse.Ado OKのパターン
またこれだと、先の例のようにGlimpseDbConnectionとかGlimpse独自の要素が登場しないので、実装としても綺麗でいいですね。SQL Serverでやる場合も、多分こっちのやり方で書いたほうが良いように思います。
ちなみに、ODPが用意している「Oracle.DataAccess.Client.OracleClientFactory」を使った場合は上手く動きませんでした。MySQLの場合はそれでもうまくいっている?ようなので、このあたりはプロバイダの実装具合で差があるのかもしれません。
プロバイダ独自のものでNGな場合は、とりあえずSystem.Data.Common.DbProviderFactories.GetFactoryを試してみると良いかもしれませんね。