【问题标题】:NHibernate second-level caching with multi-queryNHibernate 二级缓存与多查询
【发布时间】:2011-09-07 13:09:19
【问题描述】:
我们广泛使用 NHibernate 多查询功能并遇到奇怪的行为。似乎 NHibernate 不缓存多查询,它们总是命中数据库。我们正在使用 QueryOver,所有查询都设置为可缓存,但是当使用 blitz.io 和 -p 1-250:30 模式测试主页时,我可以看到唯一命中数据库的多查询被执行了 2000 多次,而其他查询(如选择当前登录的用户)只执行一次或两次。
所以问题是:是我遗漏了什么还是 NHibernate 没有真正缓存多查询结果?
【问题讨论】:
标签:
nhibernate
multi-query
【解决方案1】:
啊哈,明白了!事实证明,这并不是所有二级缓存的错,而是我们使用 QueryOver 的错。
在我们编写多租户 SaaS 应用程序时,我们的大多数查询看起来像这样:
return
Session.QueryOver<Article>().Cacheable().
Where(a => a.Site == site && a.PublishedAt <= publishedAt).
OrderByCoalesceDesc(typeof(DateTime), a => a.UpdatedAt, a => a.CreatedAt).
Take(count).
Future();
a.Site == site 是问题所在。显然,查询缓存检查查询结果是否被缓存的方式基本上是使用一条 SQL 语句和所有参数的组合作为缓存“哈希表”的键。对于我们的多查询,SQL 语句文本总是相同的,但 site 参数是罪魁祸首。 NH 检查所有提供的参数是否与缓存中的参数匹配,当然我们的Site 类中没有实现Equals(),因此检查总是失败。
我们最终的结果是像这样重写我们的查询:
var siteID = site.ID;
return
Session.QueryOver<Article>().Cacheable().
Where(a => a.Site.ID == siteID && a.PublishedAt <= publishedAt)...