我有一个类别映射:
<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&#34; = 4128768)。然后根据nHibernate它应该在会话缓存中,它不应该再次命中DB。
我错在哪里?我是......
请帮助我!!
答案 0 :(得分:0)
您遇到的问题是正确的,因为实际上您正在发出两个不同的查询。在执行第二个查询时 - 不清楚,是否/第二个将返回第一个查询的子集结果。 NHibernate不提供任何比较,如:没有WHERE的查询包含所有结果作为带有一些WHERE子句的查询。例如,仍然可能有不同的页面...
默认情况下,NHibernate会缓存查询(使用相同的参数)以及返回的ID结果集。对于每个ID,还有实体缓存。因此,如果您懒惰地加载东西,则使用已加载的实体(在其ID的第一级缓存)。
但在这种情况下 - 两个查询都不一样。它们具有不同的参数(并且 - 通常 - 在同一事务中已经发生了一些写操作)
.Add(Restrictions.Eq("CategoryId", 4128768))