如何转换不带参数的缓存未命中检索 Func 以便它接受整数参数?
How can I convert cache-miss retrieval Func with no parameters so that it will accept an integer parameter?
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;
}
How can I supply a parameter to a Func
which doesn't accept any parameters
TL;DR
通过关闭它来使用 lambda 捕获作用域变量。
说明
而不是在缓存未命中 Func
中使用 method group syntax,您需要将其替换为具有零参数的函数 - 这是一个使用捕获的 lambda 的示例companyId
:
return GetObjectFromCache<List<DepartmentsModel>>($"AllDepartmentsForCompany{companyId}",
60 * 8,
() => GetDepartmentsByCompanyDB(companyId));
基本原理:在采用单个参数的函数上使用方法组语法等同于:
x => GetDepartmentsByCompanyDB(x)
这不起作用,因为缓存未命中所需的 Func
不带任何参数 - GetObjectFromCache
在这种情况下不提供参数 x
:
cachedObject = objectSettingFunction(); // No parameter
您仍然可以通过在 lambda 中关闭它来捕获 companyId
。
缓存键错误
我还认为您的缓存密钥中存在逻辑错误
string.Format("Departments{0}", "ALL")
对我来说没有意义 - 您正在缓存给定公司的所有部门。您将需要在缓存键中使用 companyId
,否则在缓存命中期间所有公司都将 return 相同的部门。
我认为缓存键应该更符合以下内容:
$"AllDepartmentsForCompany{companyId}"
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;
}
How can I supply a parameter to a
Func
which doesn't accept any parameters
TL;DR
通过关闭它来使用 lambda 捕获作用域变量。
说明
而不是在缓存未命中 Func
中使用 method group syntax,您需要将其替换为具有零参数的函数 - 这是一个使用捕获的 lambda 的示例companyId
:
return GetObjectFromCache<List<DepartmentsModel>>($"AllDepartmentsForCompany{companyId}",
60 * 8,
() => GetDepartmentsByCompanyDB(companyId));
基本原理:在采用单个参数的函数上使用方法组语法等同于:
x => GetDepartmentsByCompanyDB(x)
这不起作用,因为缓存未命中所需的 Func
不带任何参数 - GetObjectFromCache
在这种情况下不提供参数 x
:
cachedObject = objectSettingFunction(); // No parameter
您仍然可以通过在 lambda 中关闭它来捕获 companyId
。
缓存键错误
我还认为您的缓存密钥中存在逻辑错误
string.Format("Departments{0}", "ALL")
对我来说没有意义 - 您正在缓存给定公司的所有部门。您将需要在缓存键中使用 companyId
,否则在缓存命中期间所有公司都将 return 相同的部门。
我认为缓存键应该更符合以下内容:
$"AllDepartmentsForCompany{companyId}"