連載:ADO.NET Entity Framework入門

第4回 データベースからのEntity Data Model生成

WINGSプロジェクト 土井 毅 著/山田 祥寛 監修
2010/09/10
Page1 Page2 Page3

ストアド・プロシージャの呼び出し

 さて、データベースからのリバースによるEDMの生成では、テーブルだけでなくストアド・プロシージャもEDMに含めることができたが、そのままではストアド・プロシージャを呼び出すことはできない。Entity Frameworkからストアド・プロシージャを呼び出すには、さらにストアド・プロシージャをEDMの関数としてインポートするという手順が必要である。

 Visual Studioの画面右にある[モデル ブラウザー]ウィンドウ(図6)を確認してみよう。このモデル・ブラウザは、概念モデルと論理モデルに存在するオブジェクトをまとめて表示する機能である*1。上部(AddressBookModelノード以下)が概念モデルを、下部(AddressBookModel.Storeノード以下)が論理モデルを表している。

*1 厳密にいえば、第1回で扱った、概念モデル定義であるCSDLと、論理モデル定義であるSSDLで定義されているオブジェクトのブラウザである


図6 [モデル ブラウザー]ウィンドウ
update_ageストアド・プロシージャが論理モデル内に定義される。

 リバース後、ストアド・プロシージャは画面下の論理モデルに定義されており、画面上の概念モデルには定義されていない。概念モデルに取り込むため、論理モデルのupdate_ageの上で右クリックし、[関数インポートの追加]を実行しよう。

 [関数インポートの追加]ダイアログ(図7)が開くので、[関数インポート名]として「UpdateAge」を指定する。これにより、update_ageストアド・プロシージャをUpdateAgeという名前のオブジェクト・コンテキストのメソッドとして呼び出すことができる。


図7 [関数インポートの追加]ダイアログ
概念モデルでの関数名や戻り値を設定できる。

 モデル・ブラウザでも、概念モデルの[関数インポート]という項目に、UpdateAgeという名前でインポートされていることを確認できる。


図8 [モデル ブラウザー]ウィンドウ
[関数インポート]項目にUpdateAgeがインポートされている。

 また、自動生成されたコードと呼び出し例はリスト2のようになる。

// インポートされたストアド・プロシージャの定義
public int UpdateAge(global::System.String name, Nullable<global::System.Int32> age)

// 呼び出しの例
container.UpdateAge("Doi", 25);
' インポートされたストアド・プロシージャの定義
Public Function UpdateAge(name As Global.System.String, age As Nullable(Of Global.System.Int32)) As Integer

' 呼び出しの例
container.UpdateAge("Doi", 25)
リスト2 インポートされたストアド・プロシージャの定義と呼び出し例

 ストアド・プロシージャの引数が適切に.NETの型として変換されており、通常のメソッドを呼ぶのと同じ形式で呼び出しが可能である点に注目しよう。ここではSQLのUPDATE文を実行するストアド・プロシージャを例に扱ったため、戻り値は変更を及ぼした行数となり、.NETの整数型として扱われている。

 なお、SQLのSELECT文を実行するストアド・プロシージャの場合は、エンティティのコレクションを返す関数としてインポートすることも可能である。

 このように、ストアド・プロシージャは厳密な型指定でプログラムからの呼び出しができるため、前回扱ったネイティブSQLに比べ、より扱いやすい方法といえるだろう。

 なお、Entity Frameworkでのストアド・プロシージャの呼び出しは、今回のように明示的に関数として呼び出す方法のほかに、エンティティの挿入、更新、削除処理のデータベースへの反映に合わせてストアド・プロシージャを実行する方法がある。この詳細については、MSDNの「チュートリアル: ストアド プロシージャへのエンティティのマッピング」を参照してほしい。

【コラム】ネイティブSQLのクエリ結果をエンティティのコレクションとして取得する

 本文で確認したように、ストアド・プロシージャは関数としてインポートすることにより、厳密な型指定によって呼び出すことができる。一方、前回解説したネイティブSQLは、文字列として実行する関係上、事前に関数としてインポートすることはできず、コンパイル時に引数や戻り値をチェックすることはできない。

 しかし、リスト3のように、クエリを実行するExecuteStoreQueryメソッドに型パラメータとしてエンティティ・クラスを渡すことで、結果をエンティティのコレクションとして取得することは可能である。

// ネイティブSQLによるクエリ結果を
// Categoryクラスのコレクションで取得
foreach (var category
              in container.ExecuteStoreQuery<Category>(
                  "select * from categories"))
{
  Console.WriteLine(string.Format("{0}", category.CategoryName));
}
' ネイティブSQLによるクエリ結果を
' Categoryクラスのコレクションで取得
For Each category
            In container.ExecuteStoreQuery(Of Category)(
                "select * from categories")
  Console.WriteLine(String.Format("{0}", category.CategoryName))
Next
リスト3 ネイティブSQLのクエリ結果をエンティティのコレクションとして取得する

 データベース構造への依存が強くなってしまうため、Entity Frameworkの理念には反する面もあるが、1つのテクニックとして記しておく。



 INDEX
  ADO.NET Entity Framework入門
  第4回 データベースからのEntity Data Model生成
    1.データベースからのEDM生成
  2.ストアド・プロシージャの呼び出し
    3.複合型の活用/まとめ
 
インデックス・ページヘ  「ADO.NET Entity Framework入門」


Insider.NET フォーラム 新着記事
  • 第2回 簡潔なコーディングのために (2017/7/26)
     ラムダ式で記述できるメンバの増加、throw式、out変数、タプルなど、C# 7には以前よりもコードを簡潔に記述できるような機能が導入されている
  • 第1回 Visual Studio Codeデバッグの基礎知識 (2017/7/21)
     Node.jsプログラムをデバッグしながら、Visual Studio Codeに統合されているデバッグ機能の基本の「キ」をマスターしよう
  • 第1回 明瞭なコーディングのために (2017/7/19)
     C# 7で追加された新機能の中から、「数値リテラル構文の改善」と「ローカル関数」を紹介する。これらは分かりやすいコードを記述するのに使える
  • Presentation Translator (2017/7/18)
     Presentation TranslatorはPowerPoint用のアドイン。プレゼンテーション時の字幕の付加や、多言語での質疑応答、スライドの翻訳を行える
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

注目のテーマ

Insider.NET 記事ランキング

本日 月間