Reputation: 555
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);
}
}
}
Upvotes: 0
Views: 944
Reputation: 2201
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");
Upvotes: 2
Reputation: 1058
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();
Upvotes: 0