5

ウェブサイトのメニューを作成しようとしています。以下の要件を満たす必要があります

  • メニュー構造を構築するためにDBからデータを引き出して、データベース駆動型でなければなりません
  • DB からプルされるデータはキャッシュする必要があります - ページ要求ごとに DB にアクセスしたくありません

現時点では、単純な例を実行していますが、キャッシュを統合する方法がわかりません。これを行う方法全体を作り直す必要があるかもしれないと思います。ここにあります:

DB からデータを取得し、ViewData に格納する ProductMenuAttribute があります

public class ProductMenuAttribute: FilterAttribute, IActionFilter
{
    #region IActionFilter Members

    public void OnActionExecuted(ActionExecutedContext filterContext)
    {
        if (filterContext != null)
        {
            var context = filterContext.Result as ViewResult;
            if (context != null)
            {
                ProductsRepository repository = new ProductsRepository(Properties.Settings.Default.SqlConnectionString);

                context.ViewData.Add("ProductsList", repository.GetAllProductRanges());
            }
        }
    }

    public void OnActionExecuting(ActionExecutingContext filterContext)
    {

    }

    #endregion
}

私のSite.masterでは、ViewDataからデータを取得し、それを使用してメニューをレンダリングします。これは、順序付けされていないメニュー リストの小さなスニペットで、CSS を使用してスタイルが設定されます。コードは次のとおりです。

            <li>
                <%= Html.ActionLink("Products", "Index", "Products")%>

                <%  IQueryable<ProductRange> productRanges = ViewData["ProductsList"] as IQueryable<ProductRange>; %>

                    <% if (productRanges != null)
                       { %>

                    <ul>
                        <% foreach (ProductRange range in productRanges) 
                           { %>   
                            <li><%= Html.ActionLink(range.Name, "RangeDetails", "Products", new { id = range.ID }, null)%></li>
                        <% } %>
                    </ul>

                    <% } %>
            </li>

次に、次のように[ProductMenu]属性を使用して各コントローラーを装飾します。

[ProductMenu]
public class HomeController : BaseController
{
    public ActionResult Index()
    {
        return View();
    }

    public ActionResult About()
    {
        return View();
    }
}

これで、コントローラーのいずれかのアクションがヒットするたびに、 ProductMenuAttributeクラスのOnActionExecutedメソッドが呼び出され、ViewData が設定され、最終的にSite.Masterで使用されて DB からメニューが構築されます。私はアクションのいずれかを呼び出します。

今の問題は、このシナリオにキャッシュを追加するにはどうすればよいですか?? どこから始めればよいのか見当もつかないし、私が持っている解決策はキャッシュ可能ではないと感じています。

4

3 に答える 3

6

私が本当に探しているのは、MVC Futures プロジェクトのHtml.RenderAction()ヘルパー拡張機能を使用することだと思います。

アイデアは、上記を使用してコントローラーでアクションを呼び出すことです。これにより、DB からデータをプルすることによって HTML メニュー構造が生成されます。次に、単純な出力キャッシュを使用して、データを数分間キャッシュします..

これは、私が望むものを達成するためにこれまでに見つけた最も簡単なアプローチです。

編集: Phil Haack が最近これについてブログを書きました - Html.RenderAction と Html.Action。すべての問題の説明とともに、私の正確なニーズをすべてカバーする素晴らしいブログ投稿。

キャッシュを正しく機能させるには、次のように OutputCaching ディレクティブを設定して、ViewUserControlHtml.RenderAction()に呼び出しを配置する必要があります。

<@ OutputCache Duration="100" VaryByParam="None" %>

次に、上記を で呼び出すとHtml.RenderPartial()、ほら、すべてうまくいきます!

于 2010-02-09T13:21:17.487 に答える
1

リポジトリを変更してキャッシュ対応にすることができます: この 2 つの質問を参照してください: cached repositoryhttp cache

于 2009-12-28T11:30:07.573 に答える
0

Enterprise Library Caching ブロックを使用してこれを行いました。キャッシュされたデータをチェックし、キャッシュされたデータがない場合は、データベース内のデータから html 文字列を作成してキャッシュに入れるので、後でキャッシュされたデータを検索するときにプレーン文字列を出力できます:D

それを行うためのコードは静的クラスにあったことに言及してください。例を投稿しますが、MVC2 でそのアプリをゼロから書き直していますので、手作業でコードを持っていません。

于 2010-10-31T15:24:15.523 に答える