如何缓存此类查询的结果:
Session.Query<Entity>().Count(e=> e.Property == someConstant)
我不能放在Cacheable()
它之后,如果我把它放在 Count() 之前,它会获取整个结果集,不是吗?
如何缓存此类查询的结果:
Session.Query<Entity>().Count(e=> e.Property == someConstant)
我不能放在Cacheable()
它之后,如果我把它放在 Count() 之前,它会获取整个结果集,不是吗?
在计数之前添加 Cacheable会导致聚合计数结果被缓存。从下面我的示例生成的 SQL 可以看出这一点。
域和映射代码
public class Entity
{
public virtual long id { get; set; }
public virtual string name { get; set; }
}
public class EntityMap : ClassMap<Entity>
{
public EntityMap()
{
Id(x => x.id).GeneratedBy.Identity();
Map(x => x.name);
Cache.ReadOnly();
}
}
测试代码本身。
using (var session = NHibernateHelper.OpenSession())
using (var tx = session.BeginTransaction())
{
session.Save(new Entity() { name = "Smith" });
session.Save(new Entity() { name = "Smithers" });
session.Save(new Entity() { name = "Smithery" });
session.Save(new Entity() { name = "Smith" });
tx.Commit();
}
String name_constant = "Smith";
using (var session = NHibernateHelper.OpenSession())
using (var tx = session.BeginTransaction())
{
var result = session.Query<Entity>().Cacheable().Count(e => e.name == name_constant);
}
using (var session = NHibernateHelper.OpenSession())
using (var tx = session.BeginTransaction())
{
var result = session.Query<Entity>().Cacheable().Count(e => e.name == name_constant);
}
从上面的代码生成的 SQL 可以在下面看到。如您所见,有四个INSERT
语句,每个语句一个session.Save
。尽管有两个查询,但只有一个SELECT
,每个查询都在单独的会话下执行。这是因为计数的结果已经被 NHibernate 缓存了。
NHibernate: INSERT INTO [Entity] (name) VALUES (@p0); select SCOPE_IDENTITY();
@p0 = 'Smith' [Type: String (4000)]
NHibernate: INSERT INTO [Entity] (name) VALUES (@p0); select SCOPE_IDENTITY();
@p0 = 'Smithers' [Type: String (4000)]
NHibernate: INSERT INTO [Entity] (name) VALUES (@p0); select SCOPE_IDENTITY();
@p0 = 'Smithery' [Type: String (4000)]
NHibernate: INSERT INTO [Entity] (name) VALUES (@p0); select SCOPE_IDENTITY();
@p0 = 'Smith' [Type: String (4000)]
NHibernate: select cast(count(*) as INT) as col_0_0_ from [Entity] entity0_
where entity0_.name=@p0;
@p0 = 'Smith' [Type: String (4000)]
可能会导致 NHibernate 忽略Cacheable
并返回数据库的情况是:
我所知道的唯一其他会导致 NHibernate 执行两个SELECT
查询的情况是,当实体被从缓存中逐出时,无论是显式使用sessionFactory.Evict
还是缓存实体在两个调用之间过期。