-1
 public List<DepartmentsModel> GetDepartmentsByCompanyDB(int companyID){
      //How will I pass the companyID value to the function?   

      return GetObjectFromCache<List<DepartmentsModel>>(string.Format("Departments{0}", "ALL"), 60 * 8,GetDepartmentsByCompanyDB);
 }

private List<DepartmentsModel> GetDepartmentsByCompanyDB(int companyID)
{
        procurementEntities db = new procurementEntities();
        var result = (from a in db.departments
                      where a.CompanyID == companyID
                      select new DepartmentsModel
                      {
                          CompanyID = a.CompanyID,
                          DateCreated = a.DateCreated,
                          DateLastUpdated = a.DateLastUpdated,
                          ID = a.ID,
                          IsActive = a.IsActive,
                          Name = a.Code + " | " +a.Name,
                          Type = a.Type,
                          Code=a.Code

                      }).ToList<DepartmentsModel>();

        return result;

    }

 //http://www.codeshare.co.uk/blog/simple-reusable-net-caching-example-code-in-c/
private static T GetObjectFromCache<T>(string cacheItemName, int cacheTimeInMinutes, Func<T> objectSettingFunction)
    {
        ObjectCache cache = MemoryCache.Default;
        var cachedObject = (T)cache[cacheItemName];
        if (cachedObject == null)
        {
            CacheItemPolicy policy = new CacheItemPolicy();
            policy.AbsoluteExpiration = DateTimeOffset.Now.AddMinutes(cacheTimeInMinutes);
            cachedObject = objectSettingFunction();
            cache.Set(cacheItemName, cachedObject, policy);
        }
        return cachedObject;
    }
StuartLC
  • 104,537
  • 17
  • 209
  • 285
NBT
  • 35
  • 7
  • 1
    Why are you doing `string.Format("Departments{0}", "ALL")` instead of just `"DepartmentsALL"`? – Rufus L Nov 21 '17 at 04:55
  • I think your cache key should be $"AllDepartmentsForCompany{companyId}" - the EF retrieves all departments for a single company - you'll want to include that in the cache key. – StuartLC Nov 21 '17 at 04:57
  • Also, it's not legal to have two methods in the same class that have the same signature (the `private` and `public` keywords are not enough to differentiate them). – Rufus L Nov 21 '17 at 04:57

1 Answers1

1

How can I supply a parameter to a Func which doesn't accept any parameters

TL;DR

Capture a scoped variable using a lambda by closing over it.

Explanation

Instead of using the method group syntax in the cache-miss Func, you'll need to replace it with a function which has zero parameters - here's an example with a lambda which uses the captured companyId:

return GetObjectFromCache<List<DepartmentsModel>>($"AllDepartmentsForCompany{companyId}", 
 60 * 8,
 () => GetDepartmentsByCompanyDB(companyId));

Rationale: Using method group syntax on a function which takes a single parameter is equivalent to:

 x => GetDepartmentsByCompanyDB(x)

which doesn't work because the Func required by the cache miss doesn't take any parameters - GetObjectFromCache doesn't provide the parameter x in this case:

 cachedObject = objectSettingFunction();  // No parameter

You can still however capture the companyId by closing over it in the lambda.

Bad Cache Key

I also believe you have a logical bug in your caching key

string.Format("Departments{0}", "ALL")

Doesn't make sense to me - you are caching all the departments for a given company. You will need to use the companyId in the cache key, otherwise all companies will return the same Departments during a cache hit.

I believe the cache key should be something more along the lines of:

$"AllDepartmentsForCompany{companyId}"
StuartLC
  • 104,537
  • 17
  • 209
  • 285