Today I came across an NHibernate problem where I needed to select every instance of a particular base type and all its derived types from a database, apart from one particular derived type. Here is a trivial example:
public class Mammal {}
public class Dog : Mammal {}
public class Cat : Mammal {}
public class DomesticCat : Cat {}
In this case the problem was equivalent to selecting every mammal that isn't a domestic cat.
We're using the table per class hierarchy inheritance model in NHibernate which uses values in a discriminator column to determine which type is held in a particular row of the table.
Selecting the whole hierarchy is done like this:
- In HQL:
IQuery q = sess.CreateQuery("from Mammal"); IList mammals = q.List();- In Criteria:
ICriteria crit = sess.CreateCriteria(typeof(Mammal)); List mammals = crit.List();
I then needed to be able to effectively add a WHERE discriminator <> 'DomesticCat' to the end of the query. I had a quick search for this special discriminator property and for a Criteria Expression for excluding a particular type but couldn't find either.
The Solution
I finally found the solution on the WHERE clause page of the HQL chapter in the NHibernate reference. There is a special property called class which you can test against a type name in HQL or an actual type in Criteria queries e.g.
- In HQL:
IQuery q = sess.CreateQuery("from Mammal m where m.class != 'DomesticCat'"); IList mammals = q.List();- In Criteria:
ICriteria crit = sess.CreateCriteria(typeof(Mammal)); crit.Add( Expression.Not( Expression.Eq("class", typeof(DomesticCat)) ) ); List mammals = crit.List();



1 comments:
nice, i was just looking for the Crtieria equivalent of HQL class keyword.
Post a Comment