Visual Studio 2010 EF4 新機能 Model Defined Functions (MDF)
こんにちは、部内は ReMIX そして Tech·Ed モードになっています。 ReMIX で私は「 UX コンシェルジュ」というブースでアテンド予定ですので、お時間あれば立ち寄って頂ければと思います。 今日は EF4 で機能追加される Model Defined Functions (MDF) をご紹介します。 Model Defined Functions (MDF) は .NET Framework 4.0 における新機能です。機能名から予測できるとおり概念モデル (CSDL) に関数を定義することができます。定義した関数には Entity SQL や LINQ to Entities でアクセスすることが可能です。 MDF は例えば、人の年齢計算のような共通で関数化しておくと便利なものに適用するものです。 では実際の実装方法を確認してみましょう。 関数を定義するために、 CSDL に次のような <Function> 要素を持つ XML を記述する必要があります。 VS デザイナで edmx を作成した場合は、 edmx を XML エディターで開いて <ConceptualModels> 要素の子要素である < Schema> 配下の任意の場所に記述することになります。 < Function Name = ” GetAge ” ReturnType = ” Edm.Int32 ” > < Parameter Name = ” Employees ” Type = ” NorthwindModel.Employees ” /> < DefiningExpression > Edm.DiffYears(Employees.BirthDate, Edm.CurrentDateTime()) </ DefiningExpression > </ Function > XML を見ると概ね、何がしたいのかご理解頂けると思います。尚、 DefiningExpression には EntitySQL を指定します。 詳細は下記の msdn ドキュメント(英語)をご覧ください。 Conceptual Model Functions (Entity Data Model) 上記定義を行うことで次のように Entity SQL 式から GetAge 関数を呼び出すことが可能です。当然、 SQL Server など固有のデータベースには依存しない実装になります。 using ( EntityConnection con = new EntityConnection ( “Name=NorthwindEntities” )) { con Open. (); EntityCommand cmd = con.CreateCommand(); cmd.CommandText = “SELECT VALUE p from NorthwindEntities.Employees as p WHERE NorthwindModel.GetAge(p) > 60″ ; EntityDataReader edr = cmd.ExecuteReader( CommandBehavior .SequentialAccess); また、 LINQ to Entities を用いて GetAge 関数の呼び出しを行う場合、事前に Stub メソッドを定義する必要があります。 [ EdmFunction ( "NorthwindModel" , "GetAge" )] public static int newGetAge( Employees e) { throw new NotSupportedException (); } ご覧のとおり、 System.Data.Objects.DataClasses.EdmFunction 属性に先ほど CSDL に定義した Function 名と名前空間が設定されています。実行時には Stub がそのまま呼び出されるわけではなく、 CSDL の Function が実行されるよう、メソッドが生成されることになります。 これで、 LINQ to Entities を用いて MDF を呼び出すことが可能です。 using ( NorthwindEntities db = new NorthwindEntities ()) { var es = from e in db.Employees where newGetAge(e) > 60 select e; } 詳細は下記の msdn ドキュメント(英語)をご覧ください。 How to: Call Model-Defined Functions in Queries (LINQ to Entities) ちょっとパフォーマンスが心配ですが、うまく使うと便利な機能だと思います。


