ORMモドキ作成 (4)
ORMモドキのお話は今日で一段落ということで、最後は、DTOクラスからのSQL文自動生成あたりについて(・∀・)
DTOクラスからのSQL文生成は、メタ情報Builderクラスで行っています。
メタ情報Builderクラスは何をするかというと、まず、DTOクラスの型情報から対象となる(IgnoreFieldAttributeが付加されていない)プロパティを列挙して、フィールド名に変換してその一覧を取得します。
また、PKにあたる(PrimaryKeyAttributeが付加された)プロパティも列挙しておきます。
ついでに検索しやすいようにHashtableにも登録しておきます(・∀・)
クラス名とプロパティ名からフィールドの一覧が取得できたので、後はStringBuilderを使ってベタベタSQL文を構築していく処理になります。
この辺は前にETLツールもどきを作ったことがあるので、それをベースにしています。
一番単純なDELETE文の生成で言えばこんな感じですね。
簡単すぎて例としては不適切かもしれませんけど(;´Д`)
private string GetSqlDelete() { StringBuilder sb = new StringBuilder(); sb.Append( "DELETE FROM " ); sb.Append( this.tableName ); return( sb.ToString() ); }
生成するSQL文は「SELECT全フィールド」「SELECT COUNT(*)」「INSERT全フィールド」「UPDATE PK以外」「DELETE」「WHERE PK指定」です。
っというわけで、今までの処理を組み合わせて汎用的なDAO処理を構築しています。
Update用メソッドを例にとってみると、こんな実装になっています。
public int UpdateDto(object dto) { // 型情報からメタ情報(SQL文を保持するクラス)を取得 DtoMetaInfo info = GetMetaInfo( dto.GetType() ); StringBuilder sql = new StringBuilder(); sql.Append( info.SqlUpdate ); sql.Append( " " ); sql.Append( info.SqlWhere ); OracleParameter[] parameters = null; try { // 全プロパティのパラメータ構築&バインド parameters = GetParameters( dto, false ); // SQL実行 int effect = OracleHelper.ExecuteNonQuery( ConnectionString, CommandType.Text, sql.ToString(), parameters ); return( effect ); } finally { // パラメータ後処理 if ( parameters != null ) { foreach( OracleParameter parameter in parameters ) { parameter.Dispose(); } } } }
っというわけで、自分が作ったのはテーブルとDTOが1:1のみで使える単純なものなわけですが。
こういうのをより実用的にするのであれば、DTOメンバやDAOメソッドにAttributeを追加して、そこから取得できる情報で複雑なマッピングや検索条件での処理も行えるようにするといったトコロでしょうか(・∀・)
まあ、そこまでやるなら既存のフレームワークを使いますけどね(´ω`)