ASP.NET MVC から wordpress のデータを扱う(2)

次に最近投稿した一覧を表示させます。
今回は、コントローラーの PostsController::RecentPosts メソッドから作っていきますね。

■コントローラーを LINQ で作る。

public ActionResult Recent()
{
    int max = 5;
    wordpressEntities ent = new wordpressEntities();
    var model = (from p in ent.wp_posts
                    join u in ent.wp_users on p.post_author equals u.ID
                    where p.post_status == "publish"
                    orderby p.post_date descending
                    select new
                    { Post = p, User = u }
                    ).Take(max);

    return View(model);
}

投稿した人の名前(User.display_name)を表示させたいので、wp_users テーブルとリンクさせます。そていて、最初の5行だけ表示させたいので Take 関数を使っています。
このための専用のモデルを作るのは面倒なので、無名クラスを作って new { Post = p, User = u } として作成しています。

こうすると、ビュー側で

  • item.Post.post_author
  • item.User.display_name

のように参照ができるハズですね(実は、うまくいきません…)。

■ビューを作る

<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<dynamic>" %>

<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.Post.ID %></td> 
                <td><%: item.Post.post_title %></td>
                <td><%: item.Post.post_date %></td>
                <td><%: item.Post.post_author %></td>
                <td><%: item.User.display_name %></td>
                <td><%: item.Post.guid %></td>
            </tr>
        <% } %>
    </table>
    <h2>最近投稿した記事(リンク版)</h2>
    <ul>
        <% foreach (var item in Model) { %>
        <li>
            <a href="<%: item.Post.guid %>"><%: item.Post.post_title %></a>
            by <%: item.User.display_name %>
            at <%: item.Post.post_date %>
        </li>
        <% } %>
    </ul>
</asp:Content>

型無しの指定なので、ViewPage のままです。
それぞれの表示は、そんまま aspx に記述するとタイピングミスが起こるので、あらかじめコントローラー内でコーディングしたものをコピー&ペーストしました。

コントローラーで、

foreach (var item in model)
{
    Debug.Print("{0},{1}", 
        item.Post.ID, 
        item.Post.post_date,
        item.Post.post_author,
        item.User.display_name,
        item.Post.guid );
}

のように作っていくと、インテリセンスが使えて便利です。

さて、これを実行するとですね。。。実行エラーが発生するのです。

なんででしょうね?無名クラスで定義したものが、ビューのところではうまく取得できないようです。

■仕方がないのでモデルクラスを作る

という訳で、仕方がないので Posts モデルクラスを作ります。先に作った FindPosts メソッドも踏まえて、こんな感じです。

public class Posts : wp_posts 
{
    public wp_users User { get; set; }
    public wp_posts Post { get; set; }

    public IQueryable<wp_posts> FindPosts()
    {
        wordpressEntities ent = new wordpressEntities();
        var model = from t in ent.wp_posts
                    where t.post_status == "publish"
                    select t;
        return model;
    }
    public List<Posts> RecentPosts(int max)
    {
        wordpressEntities ent = new wordpressEntities();
        var model = (from p in ent.wp_posts
                        join u in ent.wp_users on p.post_author equals u.ID
                        where p.post_status == "publish"
                        orderby p.post_date descending
                        select new { Post = p, User = u }
                        ).Take(max);

        List<Posts> posts = new List<Posts>();
        foreach (var item in model)
        {
            posts.Add( 
                new Posts { Post = item.Post, User = item.User });
        }
        return posts;
    }
}

プロパティで wp_posts と wp_users のテーブルが参照できるように Post, User を定義しておきます。後は、コントローラーで作成していた LINQ の文をコピー&ペーストして、この結果を List に詰めて返します。

対して、コントローラーの RecentPosts メソッドは非常になるのでが、なんだかなぁ、という感じですね。

public ActionResult Recent()
{
    int max = 5;
    Models.Posts post = new Models.Posts();
    var model = post.RecentPosts(max);
    return View(model);
}

これを動かすと、ビューはそのままで綺麗に動きます。

一応、動くには動くのですが、wp_posts と wp_users のテーブルをいちいち join させないといけないのが CakePHP よりも劣っていますよね。

というのは、EDM(Entitiy Data Model)のところでリレーションを設定していないのが原因なのです。CakePHP では Model::$belongsTo などで join を指定しているのですが、wordpress のテーブルから引っ張ってきたテーブルでは、この join が設定されていません。

なので、お次は、リレーションを設定したうえで、最近投稿した一覧を表示させてみます。

カテゴリー: ASP.NET, Wordpress パーマリンク

ASP.NET MVC から wordpress のデータを扱う(2) への1件のコメント

  1. masuda のコメント:

    item.Post が aspx 内で参照されない件は不具合っぽいですね…
    直接 aspx に <% ... %> で model を抽出するコードを書くと動くので、controller から view に引き渡すところで、何かが違ってしまっているようです。

コメントは停止中です。