2011-04-27 70 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