简体   繁体   中英

How to add caching to my MVC Application and WCF Service

I have an MVC Web application that basically queries a SQL store procedure for a list of products,I have a WCF service layer that is responsible for the database querying, there is a call that gets products by category and return the data to MVC Grid-view. I have managed to cache on the application level by setting outputcache to a duration of 3600, this works fine, however is caches the data only after I make an initial call to each product categories, how can I make it consistent on start-up. Also how do I cache the data in the WCF service layer. Please see my code to see what I have so far. I am fairly new to MVC can you please help.

public class HomeController : Controller
{
    [OutputCache(Duration = 3600, Location = OutputCacheLocation.Client, VaryByParam = "none")]
    public ActionResult Index()
    {

        TopProductWCFService.TopProductServiceClient client = new TopProductWCFService.TopProductServiceClient();

        List<Top_100_Result> productType = client.GetTopProductsByTypeName();

        ViewBag.ProductType = new SelectList(productType.Select(x => x.Product_Type_Name).Distinct().OrderBy(x => x));

        return View("Index", productType);
    }

    [OutputCache(Duration = 3600)]
    public ActionResult ProductDescription(string ProductType)
    {
        TopProductWCFService.TopProductServiceClient client = new TopProductWCFService.TopProductServiceClient();

        List<Top_100_Result> productDesctriptionList = client.GetTopProductsByCategory(ProductType).Where(x => x.Product_Type_Name == ProductType).ToList();//new List<Top_100_Result>();

        return PartialView("_ProductDescription", productDesctriptionList);

    }



}


public class Service1 : ITopProductService
{
    //private const string CacheKey = "topProducts";

    public List<Top_100_Result> GetTopProductsByTypeName()
    {
        using (EmbraceEntities ctx = new EmbraceEntities())
        {
            var productObjects = ctx.Top_100(null);

            return new List<Top_100_Result>(productObjects.Distinct());
        }
    }


    public List<Top_100_Result> GetTopProductsByCategory(string productCategory)
    {

        using (EmbraceEntities ctx = new EmbraceEntities())
        {
            var productsCategoryList = ctx.Top_100(productCategory);

            return new List<Top_100_Result>(productsCategoryList);
        }
    }
}

To cache data from WCF service, you should have a Cache layer first. Sample code:

using System.Runtime.Caching;

public class CacheManager
{
        private static MemoryCache _cache = MemoryCache.Default;

        public static void AddToCache<T>(string key, T value)
        {
            _cache[key] = value;
        }

        public static T GetFromCache<T>(string key)
        {
            return (T)_cache[key];
        }

        public static void RemoveFromCache(string key)
        {
            _cache.Remove(key);
        }
}

Then use it in your data layer, eg:

public List<Top_100_Result> GetTopProductsByTypeName()
{
    var products = CacheManager.GetFromCache<List<Top_100_Result>>("TOP_100_RESULT");

    //Add to cache if not existed
    if (products == null)
    {
            using (EmbraceEntities ctx = new EmbraceEntities())
            {
                var productObjects = ctx.Top_100(null);

                products = new List<Top_100_Result>(productObjects.Distinct());

                CacheManager.AddToCache<List<Top_100_Result>>("TOP_100_RESULT", products);
            }
    }

   return products;
}

You should also clear cache to refresh the data as soon as the cache data becomes invalid.

CacheManager.RemoveFromCache("TOP_100_RESULT");

There are many ways how you can do that. Maybe one would be: (Pseudo code)

at the global.asax.cs

 public static Service1 MyService = new Service1();
 protected void Application_Start()
 {
     Task.CreateNew(()=>mySerivce.Init());

I would initalize your service in a task. At the init i would read the Entities() and cache them locally.

    GetTopProductsByTypeName()
    {
          return new List<Top_100_Result>(productObjectsCache.Distinct());

then you need a Update Method when the data object are changed.

 public ActionResult Index()
 {
    List<Top_100_Result> productType = WebHostApplication.MyService.GetTopProductsByTypeName();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM