score:2
Adding Cacheable before the count will cause the aggregate count results to be cached. This can be seen by the SQL generated from my example below.
Domain and 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 from the above code can be seen below. As you can see, there are four INSERT
statements, one for each session.Save
. Whereas there is only one SELECT
despite the two queries, each performing under a separate session. This is because the result of the count has been cached by 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)]
The possible scenarios which will cause NHibernate to ignore Cacheable
and go back to the DB are when:
- The second level cache is not enabled in the session factory configuration.
- The entity has not been marked as cacheable.
The only other scenario I know of that will cause NHibernate to perform two SELECT
queries is when the entity has been evicted from the cache, either explicitly using sessionFactory.Evict
or by the cached entity becoming expired between the two calls.
Source: stackoverflow.com
Related Articles
- Getting count with NHibernate + Linq + Future
- NHibernate Second Level Cache With NHibernate Linq Provider 1.0
- NHIbernate (3.1) - Linq group by then order by count issue
- LINQ Source Code Available
- Compiled LINQ queries - NHibernate
- creating Linq to sqlite dbml from DbLinq source code
- Does LINQ convert code to SQL queries
- NHibernate LINQ query performance, which code fragment is better?
- LINQ TO Nhibernate Count
- linq difference between two select count queries
- source code for LINQ 101 samples
- NHibernate LINQ count number of groups in query
- Linq to NHibernate - select count problem
- NHIbernate Linq group by count
- NHibernate Futures using Linq to query count
- NHibernate LINQ queries with nested .Any() conditions
- NHibernate Linq Query - Select Sub Queries
- NHibernate LINQ solution to count SUM
- Simplify the following code to a one-liner using Linq queries
- How to select the least count of items in fluent nHibernate via a linq query?
- c# Linq or code to extract groups from a single list of source data
- null reference exception in Count of linq to nhibernate query
- Linq To Nhibernate - Separated queries
- Distinct Count and SUM sub queries in Joined LINQ to SQL
- Convert string[] to int[] in one line of code using LINQ
- LINQ with groupby and count
- Code equivalent to the 'let' keyword in chained LINQ extension method calls
- LINQ - Left Join, Group By, and Count
- Linq with group by having count
- NHibernate vs LINQ to SQL
- C# if statment inside LINQ select clause
- include keyword not providing filter with extension method
- Add watch window shows value but the value is not assigned to variable
- NULL Subcollections in framework, OK in LINQPad
- Get maximums of list using Linq?
- linq join on null
- Setting up databind for a listview using c#
- C# Merge 2 list of IP
- Converting a Dictionary to a List with formatting
- SELECT NEW with a potentially null field using LINQ and Entity Framework
- How to convert array to dictionary
- Rearrange a list based on given order in c#
- Order query Results by Enum Name
- The specified type member 'UserName' is not supported in LINQ to Entities
- How to write unit test for methods using nHibernate
- Get last several values from model
- Finding an item in a list of anonymous objects in C#
- KeyValuePair nullable problem with property
- LIKE operator in FromSqlInterpolated/FromSqlRaw not working, but fluent API or LINQ expressions do
- ObservableCollection projections that is also observable