0

I'm trying to cache data like application resources which already stored in database.

How do I implement memory cache with SQL cache dependency in .NET Core?

TylerH
  • 20,799
  • 66
  • 75
  • 101

2 Answers2

0

If your database supports SQL Dependency, you can use it to remove or add the item back to the cache. When OnChange is invoked, either remove the item from the cache or insert the item again.

public class CacheWithDbDependency {
    IMemoryCache _cache;
    public CacheWithDbDependency(IMemoryCache cache) {
        _cache = cache;
    }
    private void dep_OnChange(object sender, SqlNotificationEventArgs e) {
        // Here remove or reinsert your item with latest data
    }
    public AddWithDbDependency(string Key, object value) {
        SqlDependency dep = new SqlDependency(com);
        dep.OnChange += new OnChangeEventHandler(dep_OnChange);
        _cache.SetValue(your data);
    }
}

Otherwise, you have to query the data and determine change after some interval and invalidate the data.

Adrian Mole
  • 49,934
  • 160
  • 51
  • 83
Siraj ur Rahman
  • 213
  • 3
  • 13
0

ASP.NET Core supports several different caches. The simplest cache is based on the IMemoryCache.

you can use the bellow code to caches.

I have interface ICacheManagement

public interface ICacheManagement
{
    T GetValue<T>(object key, T defaultValue = default(T));
    void SetValue<T>(object key, T value, int timeoutInSeconds);
    void SetSlidingValue<T>(object key, T value, int timeoutInSeconds);
    void Remove(object key);
    void Remove(List<object> keys);
    void ClearTableCache(string tableName);
    void ClearTableCache(List<string> tableName);
    void ClearAllCaches();

}

class CacheManagement

public class CacheManagement : ICacheManagement
{
    private readonly IMemoryCache _memoryCache;
    public CacheManagement(IMemoryCache memoryCache)
    {
        _memoryCache = memoryCache;
    }
    public T GetValue<T>(object key, T defaultValue = default) 
        => _memoryCache.TryGetValue<T>(key, out var cacheValue) ? cacheValue : defaultValue;

    public void SetValue<T>(object key, T value, int timeoutInSeconds) =>
        _memoryCache.Set<T>(key, value, new MemoryCacheEntryOptions()
            .SetAbsoluteExpiration(TimeSpan.FromSeconds(timeoutInSeconds)));

    public void SetSlidingValue<T>(object key, T value, int timeoutInSeconds) =>
        _memoryCache.Set<T>(key, value, new MemoryCacheEntryOptions()
            .SetSlidingExpiration(TimeSpan.FromSeconds(timeoutInSeconds)));

    public void Remove(object key) => _memoryCache.Remove(key);

    public void Remove(List<object> keys) => keys.ForEach(Remove);

}

Use cache, I assume you have a Customer class and a repository for it

public class CustomerRepository
{
    private readonly ICacheManagement _cacheManagement;

    public CustomerRepository(ICacheManagement cacheManagement)
    {
        _cacheManagement = cacheManagement;
    }

    public IEnumerable<Customer> GetAllSetting()
    {
        string cacheKey = $"cacheKey";

        IEnumerable<Customer> listSetting = _cacheManagement.GetValue<IEnumerable<Customer>>(cacheKey, null);
        if (listSetting != null)
            return listSetting;

        IEnumerable<Customer> setting = ...; //get data from database

        int temporaryCacheExpireInSeconds = 20;//time cache for this cacheKey
        _cacheManagement.SetValue<IEnumerable<Customer>>(cacheKey, setting, temporaryCacheExpireInSeconds);

        return setting;
    }
}
Reza Jenabi
  • 3,884
  • 1
  • 29
  • 34