c# - How to cache .Count() queries in NHibernate.Linq? -
how cache result of such query:
session.query<entity>().count(e=> e.property == someconstant)
i cannot place cacheable()
after it, , if place before count(), fetch entire result set, wouldnt it?
adding cacheable before count will cause aggregate count results cached. can seen sql generated example below.
domain , mapping code
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(); } }
the test code itself.
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); }
the sql generated above code can seen below. can see, there 4 insert
statements, 1 each session.save
. whereas there 1 select
despite 2 queries, each performing under separate session. because result of count has been cached nhibernate.
nhibernate: insert [entity] (name) values (@p0); select scope_identity(); @p0 = 'smith' [type: string (4000)] nhibernate: insert [entity] (name) values (@p0); select scope_identity(); @p0 = 'smithers' [type: string (4000)] nhibernate: insert [entity] (name) values (@p0); select scope_identity(); @p0 = 'smithery' [type: string (4000)] nhibernate: insert [entity] (name) values (@p0); select scope_identity(); @p0 = 'smith' [type: string (4000)] nhibernate: select cast(count(*) int) col_0_0_ [entity] entity0_ entity0_.name=@p0; @p0 = 'smith' [type: string (4000)]
the possible scenarios cause nhibernate ignore cacheable
, go db when:
- the second level cache not enabled in session factory configuration.
- the entity has not been marked cacheable.
the other scenario know of cause nhibernate perform 2 select
queries when entity has been evicted cache, either explicitly using sessionfactory.evict
or cached entity becoming expired between 2 calls.
Comments
Post a Comment