没有从会话缓存中获取数据,而是访问DB

本文关键字:访问 DB 数据 获取 会话 缓存 | 更新日期: 2023-09-27 18:04:18

我有一个映射类别:

<class name="Category" table="Category" lazy="true">
        <cache usage="read-write"/>   // enabled Entity Cache
        <id name="CategoryId" column="pk_cat_id">
          <generator class="hilo"/>
        </id>
        <property name="Name" column="name" type="string" length="50" />
        <many-to-one name="ParentCategory" class="Category" 
                     column="parent_cat_id" cascade="save-update"/>
        <bag name="childCategories" cascade="all" inverse="true">
          <key column="parent_cat_id"/>
          <one-to-many class="Category"/>      
        </bag>
</class>
我写的

:

    using (ISession sess = factory.OpenSession())
    using (ITransaction tran = sess.BeginTransaction())
    {
        IList<Category> products = sess.CreateCriteria(typeof(Category))
                                       .SetCacheable(true)
                                       .List<Category>();   // hits DB -- no issues
        IList<Category> prod = sess.CreateCriteria(typeof(Category))
                                 .SetCacheable(true)
                                 .Add(Restrictions.Eq("CategoryId", 4128768))
                                 .List<Category>();        // hits DB  -- WHY?
        tran.Commit();
    }
从上面可以看到,对于第一个查询,它获取表中的所有行。第二次,当我试图访问作为第一次查询(CategoryId"= 4128768)的结果已经存在的行之一。然后根据nHibernate,它应该在会话缓存中,它不应该再次击中DB。

我错在哪里?

请帮帮我!!

没有从会话缓存中获取数据,而是访问DB

您所经历的是正确的,因为实际上,您正在发出两个不同的查询。在执行第二个查询时,尚不清楚第二个查询是否会返回第一个查询的子集结果。NHibernate不提供任何比较,比如:不带WHERE的查询包含所有结果,就像带WHERE子句的查询一样。例如,仍然可以有不同的页面…

默认情况下,NHibernate执行缓存查询(使用相同的参数)和返回id的结果集。对于每个ID,还有一个实体缓存。因此,如果您延迟加载内容,则使用已经加载的实体(根据其ID缓存在第一层)

但是在这种情况下-两个查询是不一样的。它们确实有不同的参数(而且-通常-在同一个事务中已经可能发生一些写操作)

  1. no WHERE子句
  2. from .Add(Restrictions.Eq("CategoryId", 4128768))