6

我正在开发一个带有 wcf-service 数据层的类似 webshop 的 asp.net mvc 4 网站。我的应用程序是使用主类别、子类别和产品构建的。每个产品只能在一个子类别中,我的网址是这样的:

/maincategoryname/subcategoryname/{productid}/producttitle

以及相应的面包屑路径:

首页 > 主分类 > 子分类 > 产品标题

我目前正在使用 MvcSitemapProvider 来生成我的导航菜单和面包屑。我将所有 url 加载为没有缓存的动态节点。这个解决方案适用于几个产品,但是当我添加 1000 个产品时,站点地图需要 6.5 秒才能填充,这太长了。

我在 MvcSitemapProvider 中打开了缓存。这样应用程序加载速度更快。但是当用户添加一个新产品并导航到这个新产品(页面)时。该网址尚未在站点地图文件中,因为它使用缓存。这样我的导航和面包屑就不会生成。

我的问题是:

用户添加新产品后,是否可以在运行时向站点地图添加新节点?

4

2 回答 2

5

接受的答案现在有点过时了。在 MvcSiteMapProvider v4 中,DynamicNodeProvider 中不再有 GetCacheDescription() 方法。无论如何,这似乎不起作用。

您现在可以通过在更新数据的操作方法上使用 [SiteMapCacheRelease] 属性来手动使缓存无效:

[MvcSiteMapProvider.Web.Mvc.Filters.SiteMapCacheRelease]
[HttpPost]
public ActionResult Edit(int id)
{

    // Update the record

    return View();
}

或者通过调用静态方法:

MvcSiteMapProvider.SiteMaps.ReleaseSiteMap();

您现在还可以选择扩展框架以提供您自己的缓存依赖项。

于 2013-08-18T11:16:42.560 回答
0

MvcSiteMapProvider 允许解决缓存依赖关系的动态站点地图。

您可以通过创建一个实现IDynamicNodeProvider. 下面是一个基于数据库查询生成动态节点的示例,并且还设置了对同一查询的缓存依赖关系。

public class ProductNodesProvider : IDynamicNodeProvider
{
  static readonly string AllProductsQuery = 
    "SELECT Id, Title, Category FROM dbo.Product;";
  string connectionString = 
        ConfigurationManager.ConnectionStrings ["db"].ConnectionString;

  /// Create DynamicNode's out of all Products in our database
  public System.Collections.Generic.IEnumerable<DynamicNode> GetDynamicNodeCollection()
  {
    var returnValue = new List<DynamicNode> ();

    using (SqlConnection connection = new SqlConnection(connectionString)) {
      SqlCommand command = new SqlCommand (AllProductsQuery, connection);
      connection.Open ();
      SqlDataReader reader = command.ExecuteReader ();
      try {
        while (reader.Read()) {
          DynamicNode node = new DynamicNode (); 
          node.Title = reader [1]; 
          node.ParentKey = "Category_" + reader [2]; 
          node.RouteValues.Add ("productid", reader [0]);

          returnValue.Add (node); 
        }
      } finally {
        reader.Close ();
      }
    }

    return returnValue;
  }

  /// Create CacheDependancy on SQL
  public CacheDescription GetCacheDescription ()
  {
    using (SqlConnection connection = new SqlConnection(connectionString)) {
      SqlCommand command = new SqlCommand (AllProductsQuery, connection);
      SqlCacheDependency dependancy = new SqlCacheDependency (command);

      return new CacheDescription ("ProductNodesProvider")
      {
        Dependencies = dependancy
      };
    }
  }
}

虽然这一切都非常漂亮 - 当您的客户更改数据库中的产品时应该使缓存无效 - 整体SqlCacheDependancy可能很棘手并且依赖于 SQL Server 版本。

CacheDependacy如果您使用缓存来存储您的产品,您可以使用自定义选项。

于 2013-04-23T08:00:37.573 回答