ページ

2011年1月16日日曜日

.NET勉強中:ADO.NET Entity Framework入門 第4回 データベースからのEntity Data Model生成




VS2010 Expressの場合、論理モデルからのDB定義がうまくいかない(一部手動での処理が必要)ので、結果としてDB定義からオブジェクトマップして使わざるを得なくなっています。


既存DBからのEDM作成手順は、プロジェクト→新しい項目の追加→ADO.NET Entity Data Model選択で、この先で「データベースから生成」を選択します。これによってDB上の定義が一覧されますので、そこからO/Rマップする対象をピックアップ(チェック)していきます。記事の例ではアソシエーションが自動的に取り込まれていますが、これは中間テーブルの名前によって判断されるのでしょうか。この部分の扱いは不明確です。


この記事ではテーブル定義だけでなく、ストアドプロシジャも取り込んでいます。が、1節の段階では取り込んだといっているだけで内容も何も確認されていません。取り込まれた内容(およびマッピング)を確認するにはモデルブラウザを開きます。記事では右上とか書かれていますが、設定やオープン順序依存でどこに表示されるかは固定ではありません。モデルブラウザを確実に開くにはモデルデザイナ画面(edmxの編集画面)のコンテキストメニューから「モデルブラウザ」を指示します。私の環境では(DB)サーバブラウザのところに重なって表示されました。

モデルブラウザに表示されるものを、記事では概念モデル、論理モデルと呼んでいます(注釈で実際には違うと明記されていますが)が、DBモデルのオブジェクト表現ですね。上の方がアプリケーションから見えるオブジェクト(なので≒概念モデル)、下の方がDB定義に対応したオブジェクト(≒論理モデル)になっています。このレベルのオブジェクトを概念モデルと呼ぶにはものすごく抵抗があります(オブジェクト設計的には上のものでやっと論理モデル)。

取り込まれたストアドプロシジャは下のXXX.Store側に出現しています。このままでは使えないそうなので、これをアプリケーションレベル(要はモデルブラウザの上側)に取り込みます。ストアドプロシジャのコンテキストメニューで「関数インポートの追加」でマッピングを指定するダイアログが表示されます。

記事の例ではUpdate系で関数値が数値なので例としてはあまり面白いものではありません。私は、複数の行を返す(要はSELECT文)ストアドプロシジャを取り込んでみました。この場合インポート関数はコレクションを返すことになります。私が使ったストアドプロシジャは複数のテーブルをJOINした結果を返すので、複合型を返すことになります(次の節で解説されるのでしょうが)。ダイアログ下方の「列情報の取得」によってストアドプロシジャの結果の列情報が取り込まれますので、これを元に結果を保持する複合型を生成します。「新しい複合型の生成」によって、複合型が生成され、上の「次のコレクションを返します」のところに出現しますので、名前を適時設定します。OKを押せば、アプリケーションオブジェクトにインポートされた関数が出現します。

結果の行一つが上で定義(生成)された複合型で表現され、SELECTの結果の複数行は、複合型に対して System.Data.Objects.ObjectResult<複合型> として返されます。これはIEnumerable ですので、foreach で全結果にアクセスすることができます。


先走って上で使ってしまった「複合型」について、です。が、記事のこの節で扱っているのはもっと単純な、プログラム言語でいうところの構造体(レコード型)のDBへのマッピングですね。ですが、このレベルのものを概念モデルが使いやすくなるというのは誇大広告でしょう。可変長配列型でも扱えて論理モデルにマッピングできるなら素晴らしいのですがね。記事で扱っている例では、フラットな構造からの複合型の再構成(リファクタリング)ですが、実際には概念モデル(というよりオブジェクト設計)で出てきた構造体(クラス)をDBにマッピングできるなら素晴らしいのですが、そういうことはできないようです。となると、この機能(コラムで挙げられた名前の制限もあるため)、現状ではあまり役に立つとは思えません。

しかし複合型自体は(モデルのリファクタリングとは関係なく)、JOINしたレコードに対して自動的に生成することが可能で(これが上の節で先走って使ったもの)、こちらの方については非常に有用な機能です。むしろ、こちらの方で例示して欲しかったですね。

0 件のコメント:

コメントを投稿