【问题标题】:Not getting the data from session cache, instead hitting the DB没有从会话缓存中获取数据,而是访问数据库
【发布时间】:2014-05-20 12:42:31
【问题描述】:

我有一个类别的映射:

<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,它应该在会话缓存中并且它不应该再次命中数据库。

我哪里错了?我是……

请帮帮我!!

【问题讨论】:

    标签: c# nhibernate orm


    【解决方案1】:

    您遇到的情况是正确的,因为实际上您发出的是两个不同的查询。在执行第二个查询时 - 不清楚是否/第二个将返回第一个的子集结果。 NHibernate 不提供任何比较,例如:没有 WHERE 的查询包含所有结果,因为有一些 WHERE 子句的查询。例如,仍然可能有不同的页面......

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

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

    1. 没有 WHERE 子句
    2. .Add(Restrictions.Eq("CategoryId", 4128768)) 构建

    【讨论】:

    • 但我在我的映射中添加了:。不是实体缓存吗?
    • 1)实体缓存是当我们调用session.Get&lt;TEntity&gt;(id)时。当我们调用session.CreateCriteria() 时,它是一个查询缓存。事实是,每个查询加载的项目都缓存在实体缓存中(按 id)。但是因为您调用了 2 个 不同 查询...它们都必须执行。现在更有意义了吗?
    • 还有一件事,我的示例中的两个查询都在同一个会话中。因此,查询缓存和实体缓存在这里毫无意义,因为它们可以跨会话工作。我想这里会话缓存开始发挥作用。此外,请告诉我您在哪里阅读 session.Get(id) 是实体缓存?你有没有读过这个倒数第二段:nhforge.org/blogs/nhibernate/archive/2009/02/09/…
    • 我明白了,我在阅读“会话缓存”时错了......并考虑了查询缓存。你说的对。但原理是一样的。我会调整我的答案...
    猜你喜欢
    • 1970-01-01
    • 2021-05-23
    • 2023-04-03
    • 1970-01-01
    • 1970-01-01
    • 2020-09-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多