使用ISQLQuery返回的实体不存储在NHibernate二级缓存中?

时间:2011-02-03 14:57:37

标签: c# asp.net nhibernate

我正在尝试为查找实体使用二级缓存,因为它们只有少数几个,并且只有在特殊情况下才应更改这些实体。

如果我使用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时,返回的对象不会从缓存中选择依赖实体,而是重新选择它们。

1 个答案:

答案 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();
        }

第二个会话不会导致任何数据库命中。

确保您已配置缓存提供程序,并为您的实体启用了查询缓存和缓存。

相关问题