2013-02-05 39 views
6

Tôi đang làm việc trên trang web asp.net mvc 4 giống như webshop với trình nền tảng dịch vụ wcf. Ứng dụng của tôi được xây dựng với các danh mục chính, danh mục phụ và sản phẩm. Mỗi sản phẩm chỉ có thể ở một tiểu thể loại và của url của tôi là như thế này:Cách thêm nút MvcSitemapProvider mới vào thời gian chạy

/maincategoryname/subcategoryname/{productid}/producttitle

Và đường điều hướng tương ứng:

Trang chủ> Maincategory> mục con> Producttitle

Tôi hiện đang sử dụng MvcSitemapProvider để tạo trình đơn điều hướng và đường dẫn. Tôi đang tải tất cả các url dưới dạng các nút động mà không có bộ nhớ cache. Giải pháp này hoạt động cho một vài sản phẩm nhưng khi tôi thêm 1000 sản phẩm, sơ đồ trang web mất 6,5 giây để điền, đó là cách quá dài.

Tôi đã bật bộ nhớ đệm trong MvcSitemapProvider. Bằng cách này, ứng dụng tải nhanh hơn nhiều. Nhưng khi người dùng thêm sản phẩm mới và điều hướng đến sản phẩm mới (trang) này. Url chưa có trong tệp sơ đồ trang web vì nó sử dụng bộ nhớ cache. Bằng cách này, điều hướng và đường dẫn của tôi không được tạo.

Câu hỏi của tôi là:

Có thể thêm một nút mới vào sitemap khi chạy sau khi người dùng thêm một sản phẩm mới?

Trả lời

0

MvcSiteMapProvider cho phép Dynamic Sitemaps giải quyết cho Phụ thuộc bộ nhớ cache.

Bạn có thể bật tính năng này bằng cách tạo lớp học triển khai IDynamicNodeProvider. Dưới đây là một ví dụ tạo ra các nút động dựa trên truy vấn cơ sở dữ liệu và cũng thiết lập sự phụ thuộc bộ nhớ cache trên cùng một truy vấn đó.

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 
     }; 
    } 
    } 
} 

Trong khi điều này là tất cả đều rất tiện lợi - và nên làm mất hiệu lực bộ nhớ cache khi khách hàng của bạn thay đổi sản phẩm trong datbase - toàn bộ SqlCacheDependancy thể được khôn lanh và là SQL Server-Version phụ thuộc.

Thay vào đó, bạn có thể sử dụng tùy chọn CacheDependacy nếu bạn đang sử dụng bộ nhớ cache để lưu trữ sản phẩm của mình.

5

Câu trả lời được chấp nhận hiện đã lỗi thời một chút. Trong MvcSiteMapProvider v4, không còn phương thức GetCacheDescription() trong DynamicNodeProvider nữa. Điều này dường như không hoạt động.

Bạn có thể bây giờ invalidate the cache manually bằng [SiteMapCacheRelease] thuộc tính trên các phương pháp hành động cập nhật dữ liệu:

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

    // Update the record 

    return View(); 
} 

Hoặc bằng cách gọi một phương pháp tĩnh:

MvcSiteMapProvider.SiteMaps.ReleaseSiteMap(); 

Bạn cũng có tùy chọn để mở rộng khung thành supply your own cache dependencies.

Các vấn đề liên quan