我正在尝试为查找实体使用二级缓存,因为它们只有少数几个,并且只有在特殊情况下才应更改这些实体。
如果我使用ICriteria获取这些实体,那么这些实体将被放置在二级缓存中,但是如果我通过ISQLQuery(table-value-function)获取这些实体,则实体不会被缓存。调用.SetCacheable(true)等没有效果。
那么,是否不支持使用ISQLQuery进行二级缓存,或者我缺少一些配置设置?
修改
示例 - IIS重启后整个应用程序中的第一个查询:
var query = _session.CreateSQLQuery("SELECT {foo.*} fro dbo.foo_GetList()");
query.AddEntity("foo", typeof(Foo));
query.SetCacheable(true);
query.List<Foo>();
当上面的代码运行时,我看不到任何添加到缓存中的内容(例如,没有 NHibernate.Caches.SysCache.SysCache - 在NHibernate日志中添加新数据)。后续调用(如_session.Get(id))执行新选择。如果我用
替换以下内容var criteria = _session.CreateCriteria<Foo>();
criteria.List<Foo>();
然后实体被缓存。
此外,对我来说,当使用ISQLQuery时,返回的对象不会从缓存中选择依赖实体,而是重新选择它们。
答案 0 :(得分:3)
对我来说很好。这是一个概念证明:
类别:
public class Foo
{
public virtual int Data { get; set; }
}
映射:
<class name="Foo">
<cache usage="read-write" />
<id type="Guid">
<generator class="guid.comb" />
</id>
<property name="Data" />
</class>
测试代码:
using (var session = sessionFactory.OpenSession())
using (var tx = session.BeginTransaction())
{
session.Save(new Foo { Data = 1 });
tx.Commit();
}
using (var session = sessionFactory.OpenSession())
using (var tx = session.BeginTransaction())
{
session.CreateSQLQuery("select {foo.*} from {foo}")
.AddEntity("foo", typeof(Foo))
.SetCacheable(true)
.List();
tx.Commit();
}
using (var session = sessionFactory.OpenSession())
using (var tx = session.BeginTransaction())
{
session.CreateSQLQuery("select {foo.*} from {foo}")
.AddEntity("foo", typeof(Foo))
.SetCacheable(true)
.List();
tx.Commit();
}
第二个会话不会导致任何数据库命中。
确保您已配置缓存提供程序,并为您的实体启用了查询缓存和缓存。