NHibernate now features an intuitive, extensible criteria query API. For now, this API is less powerful than the more mature HQL query facilities. In particular, criteria queries do not support projection or aggregation.
The interface NHibernate.ICriteria represents a query against a particular persistent class. The ISession is a factory for ICriteria instances.
ICriteria crit = sess.CreateCriteria(typeof(Cat)); crit.SetMaxResults(50); List cats = crit.List();
An individual query criterion is an instance of the interface NHibernate.Expression.ICriterion. The class NHibernate.Expression.Expression defines factory methods for obtaining certain built-in ICriterion types.
IList cats = sess.CreateCriteria(typeof(Cat))
.Add( Expression.Like("Name", "Fritz%") )
.Add( Expression.Between("Weight", minWeight, maxWeight) )
.List();Expressions may be grouped logically.
IList cats = sess.CreateCriteria(typeof(Cat))
.Add( Expression.Like("Name", "Fritz%") )
.Add( Expression.Or(
Expression.Eq( "Age", 0 ),
Expression.IsNull("Age")
) )
.List();IList cats = sess.CreateCriteria(typeof(Cat))
.Add( Expression.In( "Name", new String[] { "Fritz", "Izi", "Pk" } ) )
.Add( Expression.Disjunction()
.Add( Expression.IsNull("Age") )
.Add( Expression.Eq("Age", 0 ) )
.Add( Expression.Eq("Age", 1 ) )
.Add( Expression.Eq("Age", 2 ) )
) )
.List();There are quite a range of built-in criterion types (Expression subclasses), but one that is especially useful lets you specify SQL directly.
// Create a string parameter for the SqlString below
Parameter paramName = new Parameter("someName", new StringSqlType());
IList cats = sess.CreateCriteria(typeof(Cat))
.Add( Expression.Sql(
new SqlString( new object[] {
"lower({alias}.Name) like lower(",
paramName,
")" } ),
"Fritz%",
NHibernateUtil.String )
.List();The {alias} placeholder with be replaced by the row alias of the queried entity.
You may order the results using NHibernate.Expression.Order.
IList cats = sess.CreateCriteria(typeof(Cat))
.Add( Expression.Like("Name", "F%")
.AddOrder( Order.Asc("Name") )
.AddOrder( Order.Desc("Age") )
.SetMaxResults(50)
.List();You may easily specify constraints upon related entities by navigating associations using CreateCriteria().
IList cats = sess.CreateCriteria(typeof(Cat))
.Add( Expression.Like("Name", "F%")
.CreateCriteria("Kittens")
.Add( Expression.Like("Name", "F%") )
.List();note that the second CreateCriteria() returns a new instance of ICriteria, which refers to the elements of the Kittens collection.
The following, alternate form is useful in certain circumstances.
IList cats = sess.CreateCriteria(typeof(Cat))
.CreateAlias("Kittens", "kt")
.CreateAlias("Mate", "mt")
.Add( Expression.EqProperty("kt.Name", "mt.Name") )
.List();(CreateAlias() does not create a new instance of ICriteria.)
Note that the kittens collections held by the Cat instances returned by the previous two queries are not pre-filtered by the criteria! If you wish to retrieve just the kittens that match the criteria, you must use SetResultTransformer(CriteriaUtil.AliasToEntityMap).
IList cats = sess.CreateCriteria(typeof(Cat))
.CreateCriteria("Kittens", "kt")
.Add( Expression.Eq("Name", "F%") )
.SetResultTransformer(CriteriaUtil.AliasToEntityMap)
.List();
foreach ( IDictionary map in cats )
{
Cat cat = (Cat) map[CriteriaUtil.RootAlias];
Cat kitten = (Cat) map["kt"];
}You may specify association fetching semantics at runtime using SetFetchMode().
IList cats = sess.CreateCriteria(typeof(Cat))
.Add( Expression.Like("Name", "Fritz%") )
.SetFetchMode("Mate", FetchMode.Eager)
.SetFetchMode("Kittens", FetchMode.Eager)
.List();This query will fetch both Mate and Kittens by outer join.
The class NHibernate.Expression.Example allows you to construct a query criterion from a given instance.
Cat cat = new Cat();
cat.Sex = 'F';
cat.Color = Color.Black;
List results = session.CreateCriteria(typeof(Cat))
.Add( Example.Create(cat) )
.List();Version properties, identifiers and associations are ignored. By default, null valued properties and properties which return an empty string from the call to ToString() are excluded.
You can adjust how the Example is applied.
Example example = Example.Create(cat)
.ExcludeZeroes() //exclude null or zero valued properties
.ExcludeProperty("Color") //exclude the property named "color"
.IgnoreCase() //perform case insensitive string comparisons
.EnableLike(); //use like for string comparisons
IList results = session.CreateCriteria(typeof(Cat))
.Add(example)
.List();You can even use examples to place criteria upon associated objects.
IList results = session.CreateCriteria(typeof(Cat))
.Add( Example.Create(cat) )
.CreateCriteria("Mate")
.Add( Example.Create( cat.Mate ) )
.List();