我正在对Castle AR和NH的二级缓存进行一些实验。在以下两种方法中,我可以看到缓存工作正常,但仅用于重复每个调用。换句话说,如果我为同一个PK调用RetrieveByPrimaryKey
两次,则在缓存中找到该对象。如果我两次调用RetrieveAll
,我会看到SQL只发出一次。
但是如果我用一些PK调用RetrieveAll
然后调用RetrieveByPrimaryKey
,我会看到两个SQL语句被发出。我的问题是,为什么AR不首先在缓存中寻找该实体?当然,由于先前调用了RetrieveAll
,它会在那里找到它。
public static T RetrieveByPrimaryKey(Guid id)
{
var res = default(T);
var findCriteria = DetachedCriteria.For<T>().SetCacheable(true);
var eqExpression = NHibernate.Criterion.Expression.Eq("Id", id);
findCriteria.Add(eqExpression);
var items = FindAll(findCriteria);
if (items != null && items.Length > 0)
res = items[0];
return res;
}
public static T[] RetrieveAll()
{
var findCriteria = DetachedCriteria.For<T>().SetCacheable(true);
var res = FindAll(findCriteria);
return res;
}
答案 0 :(得分:0)
您正在使用特定查询的缓存。这意味着缓存查找以下列方式完成:
在cahce中搜索具有相同语法和相同参数的查询结果。如果找到 - 使用缓存结果。
nHibernate(这与AR无关,顺便说一句)不知道逻辑,一个查询'包含'另一个。所以这就是为什么你得到2分贝的旅行。
我建议使用ISession.Get
按ID检索项目(这是推荐的方法)。我认为(虽然没有测试过)Get
可以使用其他查询缓存的项目
这是来自ayende的一个很好的blog post。