実はEDM(Entity Data Model)では、あらかじめデータベースでリレーションを設定しておくと、モデルのほうでアソシエーションが設定されます…って、なんだか分かりませんね(汗)
要は、こんな感じです。
最初の SQL Server 2008 R2 上で、リレーションを設定します。
ダイアグラムではこんな風。
このあたり、.NET ラボの勉強会で話したのですが、SQL Server Management Studio はそれなりに新しくなっていくのに、このダイアグラムは SQL Server 7.0 の頃と変わり映えしません。時代遅れなのか、誰も使っていないのかというところですが、データベース上の外部キーって大切なんですけどねぇ。
これを Visual Studio の EDM を更新すると、こんな風にアソシエーションが設定されます。
ちなみに、データベース上では「リレーション」とか「外部キー」と言われるんですが、オブジェクト指向の方(CakePHPとかも)の O/R マッピングの世界では「アソシエーション」って言っているようです。どちらでもいいんですが、統一してほしいような気が(機能が違うからっていう意味もあるでしょうが)。
こういう風にしておくと、wp_posts モデルの中に wp_users というプロパティ(ナビゲーション)が出来きます。逆向きの wp_users モデルの中にもできますね。
これのナビゲーションを使うと、wp_posts.wp_users.display_name というように、関係するテーブルの列名を表示させることができるのです。
この機能をうまく使うと、ビューが簡単になります。
■ビューを作る
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | <%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage< IEnumerable <MvcWordpress.wp_posts>>" %> < asp:Content ID = "Content1" ContentPlaceHolderID = "TitleContent" runat = "server" > Recent </ asp:Content > < asp:Content ID = "Content2" ContentPlaceHolderID = "MainContent" runat = "server" > < h2 >最近投稿した記事</ h2 > < table > < tr > < th >ID</ th > < th >post_date</ th > < th >post_title</ th > < th >post_author</ th > < th >User.display_name</ th > < th >guid</ th > </ tr > <% foreach (var item in Model) { %> < tr > < td ><%: item.ID %></ td > < td ><%: item.post_title %></ td > < td ><%: item.post_date %></ td > < td ><%: item.post_author %></ td > < td ><%: item.wp_users.display_name %></ td > < td ><%: item.guid %></ td > </ tr > <% } %> </ table > < h2 >最近投稿した記事(リンク版)</ h2 > < ul > <% foreach (var item in Model) { %> < li > < a href="<%: item.guid %>"><%: item.post_title %></ a > by <%: item.wp_users.display_name %> at <%: item.post_date %> </ li > <% } %> </ ul > </ asp:Content > |
渡されるモデルは、wp_posts のコレクションということで、IEnumerable
■コントローラーを直す
コントローラーのほうは、LINQ to Entities に直して、wp_posts テーブルだけを参照するようにします。参照先のテーブルは、自動的に読み込まれるので LINQ 自体も簡単になります。
1 2 3 4 5 6 7 8 9 10 11 | public ActionResult Recent() { int max = 5; wordpressEntities ent = new wordpressEntities(); var model = ( from p in ent.wp_posts where p.post_status == "publish" orderby p.post_date descending select p).Take(max); return View(model); } |
このあたり、CakePHP の Model::$belongsTo と同じような使い方ができます。というか、同じようにするために外部キー/アソシエーション/ナビゲーションを利用する訳です。
実行するとすんなり動きます。
こんな訳で、1段階のリレーションは簡単にできるのですが、さて、4つのリレーションの場合はどうするんでしょうねえ?