我们广泛使用 NHibernate 多查询功能并遇到奇怪的行为。似乎 NHibernate 不缓存多查询,它们总是访问数据库。我们正在使用 QueryOver,所有查询都设置为可缓存,但是在使用 blitz.io 测试主页时使用 -p 1-250:30
模式,我可以看到唯一命中数据库的多查询执行了 2000 多次,而其他查询(例如选择当前登录的用户)仅执行一次或两次。
所以问题是:我是不是遗漏了什么或者 NHibernate 并没有真正缓存多查询结果?
最佳答案
啊哈,明白了!事实证明,这不全是二级缓存的错,而是我们对 QueryOver 的使用才是罪魁祸首。
当我们编写 Multi-Tenancy 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)...
关于NHibernate 二级缓存多查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7334414/