2011-04-27 28 views
0

我嘗試了NHibernate中的第二級緩存。有了這個代碼:NHibernate的查詢緩存每行提取一個請求來獲取實體

return session.Query<Payment>() 
    .Cacheable() 
    .OrderByDescending(payment => payment.Created) 
    .Skip((page - 1)*pageSize) 
    .Take(pageSize).ToArray(); 

如果實體不在緩存中,就會導致這樣的正在執行的查詢:

select ... from Payment where Id = 1 
select ... from Payment where Id = 2 
select ... from Payment where Id = 3 

如果100行返回,這些100會被處決。即一個很大的性能問題。如果只是這樣的查詢被執行了這將是更好:

select ... from Payment where Id in (1,2,3) 

這些實體不在緩存中有可能是因爲沒有配置實體緩存,緩存中的高速緩存中的實體或大小有限制已經過期或從緩存中刪除。

爲了不被強迫依賴100%的實體緩存,是否有可能改變NHibernate查詢「缺失」實體數據的方式?

回答

1

1)是否可以配置NHibernate(我使用FluentNHibernate和automapping)來緩存實體?

是的,可以將Nhibernate二級緩存配置爲緩存實體。 請參閱Here

2)爲了不被強迫依賴100%緩存,是否有可能改變NHibernate查詢「缺少」實體數據的方式?

Did you enable "cache.use_query_cache" property in the config file?

+0

1.我設法實體緩存與FNH約定的工作。但是它不會緩存整個實體,即使我使用急切的加載,來自相關表的數據也不會被加入。 – Allrameest 2011-04-27 11:23:26

+1

2.是查詢緩存已啓用。並且查詢被緩存。但查詢緩存只包含ids。要獲取數據,他們將訪問實體緩存或每行執行一個查詢以獲取數據。 – Allrameest 2011-04-27 11:26:04

0

你需要以「激活」相同的緩存規則的集合爲主體的實體指定相同的緩存區。否則它只會緩存主實體,如果主實體從二級緩存中加載,則會再次獲取集合。

雖然我不知道這是否支持FluentNhibernate,但您需要檢查文檔。

它看起來像集合(袋)有.Cache(CacheMapping映射)支持

http://fluentnhibernate.org/api/FluentNHibernate.MappingModel/CacheMapping.htm

+0

我發現instance.Cache.IncludeAll()(http://fluentnhibernate.org/api/FluentNHibernate.Conventions.Instances/ICacheInstance.htm),但它似乎不工作... – Allrameest 2011-04-27 14:25:38

+0

你應該在你的緩存添加收集聲明。發佈你的映射。 – jishi 2011-04-27 15:05:43

+0

啊,對不起,沒有看到它不是你正在合作的收藏。然後你應該在你的實體映射中聲明CacheRegion來支付 – jishi 2011-04-27 15:06:50

相關問題