我正在尝试使用键作为谓词(Func
)来实现缓存(字典),并且值是Func
(IEnumerable)的结果。
我很难找出字典的关键字。我试过GetHashCode
(我的意思是它不会像我希望的那样工作)但是无论我传递什么谓词,我总是得到相同的哈希码。
这是我到目前为止所拥有的。
public partial class DataProvider
{
ICache Cache = new Cache();
static SemaphoreSlim dbLock = new SemaphoreSlim(1);
static List<dynamic> CachedPredicates = new List<dynamic>();
static object cacheLock = new object { };
public async Task<IEnumerable<T>> FindItems<T>(Func<T, bool> predicate) where T : IDocumentModel
{
Func<T, bool> p;
var lookUpDb = false;
List<T> c = new List<T>();
lock (cacheLock)
{
p = CachedPredicates.SingleOrDefault(x => x as Func<T, bool> == predicate);
if (p == null)
{
CachedPredicates.Add(predicate);
lookUpDb = true;
}
}
if (lookUpDb)
{
await dbLock.WaitAsync();
try
{
IDocumentQuery<T> query = AppDatabase.Client.CreateDocumentQuery<T>(UriFactory.CreateDocumentCollectionUri(ProjectCollection.DatabaseId, ProjectCollection.CollectionId))
.Where(predicate).AsQueryable()
.AsDocumentQuery();
while (query.HasMoreResults)
{
c.AddRange(await query.ExecuteNextAsync<T>());
}
}
finally
{
dbLock.Release();
}
Cache.SetItems<T>(c, predicate.GetHashCode().ToString());
return c;
}
else
{
return Cache.Items<T>(predicate.GetHashCode().ToString());
}
}
}
}
这是一个如何使用它的例子:
var v = await DataProvider.FindItems<DataTableModel>(x => x.ProjectId != string.Empty);
因此,第一次调用它时,它会查询数据库,后续调用只会从Cache
获取结果。
我已经省略了Cache
类中的代码,但如果有人看到它的相关性,我会添加它。
我们的想法是不必为传递给FindItems
的每个谓词管理每个结果的ID,只需“识别”查询的内容即可。
这有可能吗?