Thursday, June 13, 2013

NHibernate query caching

Query caching won't work using this Linq construct:

var query = 
    (from p in session.Query<Product>()
    join t in session.Query<ProductTranslation>() on p.ProductId equals l.ProductId
    where p.YearIntroduced >= 1950 && string.Compare(t.ProductName, "B") >= 0
    select new { p, t }).Cacheable();

var list = query.ToList();



Must be done this way:
var query = from p in session.Query<Product>()
            join t in session.Query<ProductTranslation>() on p.ProductId equals l.ProductId                         
            select new { p, t };

query = query.Where(q => q.p.YearIntroduced >= 1950 && string.Compare(q.t.ProductName, "B") >= 0).Cacheable();

var list = query.ToList();


If you are a one-stop-shop kind of person, you might prefer the multiple Linq statements be kept together in just one Linq statement:

var query = 
            (from q in 
                from p in session.Query<Product>()
                join t in session.Query<ProductTranslation>() on p.ProductId equals l.ProductId 
                select new { p, t }
            where q.p.YearIntroduced >= 1950 && string.Compare(q.t.ProductName, "B") >= 0
            select q).Cacheable();               

var list = query.ToList();

The above things won't be possible if a DAL/Repository component layered on top of an ORM component hides or neglect to expose useful functionality, or if there's a project policy of not allowing the developer to use NHibernate's API directly, e.g., caching, fetching



The developer should be able to access the caching API when there's a need.



"You can solve every problem with another level of indirection, except for the problem of too many levels of indirection" – D.Wheeler



Here's a case of too many indirections: http://ayende.com/blog/156577/on-umbracos-nhibernates-pullout



Happy Coding! ツ

No comments:

Post a Comment