If you don’t know the identifier(s) of the object(s) you are looking for, use the Find() methods of ISession. NHibernate supports a simple but powerful object oriented query language.
IList cats = sess.Find(
"from Cat as cat where cat.Birthdate = ?",
date,
NHibernateUtil.Date
);
IList mates = sess.Find(
"select mate from Cat as cat join cat.Mate as mate " +
"where cat.name = ?",
name,
NHibernateUtil.String
);
IList cats = sess.Find( "from Cat as cat where cat.Mate.Birthdate is null" );
IList moreCats = sess.Find(
"from Cat as cat where " +
"cat.Name = 'Fritz' or cat.id = ? or cat.id = ?",
new object[] { id1, id2 },
new IType[] { NHibernateUtil.Int64, NHibernateUtil.Int64 }
);
IList mates = sess.Find(
"from Cat as cat where cat.Mate = ?",
izi,
NHibernateUtil.Entity(typeof(Cat))
);
IList problems = sess.Find(
"from GoldFish as fish " +
"where fish.Birthday > fish.Deceased or fish.Birthday is null"
);
The second argument to Find() accepts an object or array of objects. The third argument accepts a NHibernate type or array of NHibernate types. These given types are used to bind the given objects to the ? query placeholders (which map to input parameters of an ADO.NET IDbCommand). Just as in ADO.NET, you should use this binding mechanism in preference to string manipulation.
The NHibernateUtil class defines a number of static methods and constants, providing access to most of the built-in types, as instances of NHibernate.Type.IType.
If you expect your query to return a very large number of objects, but you don’t expect to use them all, you might get better performance from the Enumerable() methods, which return a System.Collections.IEnumerable. The iterator will load objects on demand, using the identifiers returned by an initial SQL query (n+1 selects total).
// fetch ids
IEnumerable en = sess.Enumerable("from eg.Qux q order by q.Likeliness");
foreach ( Qux qux in en )
{
// something we couldnt express in the query
if ( qux.CalculateComplicatedAlgorithm() ) {
// dont need to process the rest
break;
}
}
The Enumerable() method also performs better if you expect that many of the objects are already loaded and cached by the session, or if the query results contain the same objects many times. (When no data is cached or repeated, Find() is almost always faster.) Heres an example of a query that should be called using Enumerable():
IEnumerable en = sess.Enumerable(
"select customer, product " +
"from Customer customer, " +
"Product product " +
"join customer.Purchases purchase " +
"where product = purchase.Product"
);
Calling the previous query using Find() would return a very large ADO.NET result set containing the same data many times.
NHibernate queries sometimes return tuples of objects, in which case each tuple is returned as an array:
IEnumerable foosAndBars = sess.Enumerable(
"select foo, bar from Foo foo, Bar bar " +
"where bar.Date = foo.Date"
);
foreach (object[] tuple in foosAndBars)
{
Foo foo = tuple[0]; Bar bar = tuple[1];
....
}
Recent Comments