2013年5月23日木曜日

RDBMS利用時のアーキテクチャの選択方針

全エントリのように、各アーキテクチャには一長一短あるわけですが、それでもどれかを選ばないと始まらないので、「僕だったら」こんな方針でアーキテクチャを選ぶ。というところを書きたいと思います。

バッチ系の処理


バッチ系の処理の場合、SELECTで条件に合致したレコードすべてに対して何らかの処理を行う。という形になると思います。この場合は生ADO.net(DbConnection/DbCommand/DbDataReader)が相性が良いと思います。

こいつは古き良きスタイルなので、レコードを一行一行読んで処理して、という形に自然になること。また、DBへの接続と切断をコントロールしやすいのもメリットです。対象のRDBMSに応じて、DbXxx抽象クラスの派生クラスを使うことで、それぞれのRDBMSの特性を生かした実装ができるのもいいですね。

(型あり|型無し)データセットだと、一旦まとめて読みこむ形になるので、バッチ系処理ではかえって制御が難しいように思います。

EF(Entity Framework)もバッチ処理で使いにくいわけではなさそうですが、たとえばSQLServerなんかだとロックエスカレーションによるデッドロックを回避するために、SELECT時にロックヒントを付けたりしますが、こんな感じのRDBMSごとの配慮がいちいち面倒なイメージがあります。実際にバッチ系処理で使ったことはないですが。

Webアプリケーション


Webアプリの場合はプレゼンテーション側のアーキテクチャを何にするかによると思います。僕の場合は好みの問題で、全力でASP.net MVCを推します。この場合はEFを選択するのがたぶん楽です。

どうしてもASP.net (Webフォーム)から逃げられなかった場合は、型無しデータセットかな。

その他 (2層C/S、3層C/S、Webサービス、etc...)


そのほかはケースバイケースになりますが、メリットデメリットを加味しながら、基本的には好みでEFか、型無しデータセットか、生ADO.netのいずれかを選ぶかな。この3つ以外は選択肢から除外。

ただし…


EFを使う場合は、モデルファーストかコードファーストで開発を始めるのがよいと思います。コードファーストはいろいろ批判的な意見も見かけますが、僕は結構好きです。
それと、インデクッスやトリガ、ストアドプロシージャなんかはどう使うか、何処で使うか、どのタイミングで実際に適用するか。ここら辺は十分な配慮が必要でしょう。あと、ビューは使いづらいです。多分。

型無しデータセットを使う場合は、コードのメンテナンシビリティを保つために、以下の2つを守ることがおススメです。
これを守ることで、前のエントリで列挙した型無しデータセットのデメリットがだいぶ減り、
  • DataTableの各レコードに対して、Enumerable拡張メソッドが使いやすくなり、コードが比較的きれいになる。
  • フィールドからのデータ取得時のキャストが不要になる。また、Nullableを使ってDBNullをNULLにマップできる。
と、形無しデータセットでも、少しはイマドキなコードが書けるようになります。例をあげてみましょう。たとえば、取得済みのDataTable「t」から、「Kana」順に「Name」と「Birthday」を取得してイロイロ。しかも「Birthday」はNullable。ならこんなコードになります。

DataTable t = GetTable();

foreach (var row in t.AsEnumerable().OrderBy(r => r.Field<string>("Kana")))
{
  var name = row.Field<string>("Name");
  var birthday = row.Field<DateTime?>("Birthday");
  // name,birthdayを使っていろいろ処理
}
このコードは、当然Selectメソッドで匿名クラスを作ったりしても問題なく行けます。個人的は「これなら使ってもいっか。」という気になります。

そして、生ADO.netを使う場合は、多段usingネストを減らす工夫があるとよいでしょう。

とりあえずそこは、ちょっと長くなったので別エントリで書くことにします。

0 件のコメント:

コメントを投稿