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;
}
-
1Why 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 Answers
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}"

- 104,537
- 17
- 209
- 285