The Inquisitive Coder – Davy Brion's Blog

Trying to walk that thin line between intelligence and ignorance

Using SQL Functions in Criteria Restrictions

Posted by Davy Brion on April 30th, 2009

A coworker needed to use a SQL function in the where clause of a query that he was creating with NHibernate’s ICriteria API. Most examples of this on the web use HQL instead of the ICriteria API and since we primarily use the ICriteria API we looked into how to do this.

Turns out it is pretty simple to do, though the syntax isn’t really straightforward. Suppose you want to query all of your employees who are born in a specific year. You could mess around with some DateTime parameters, but most databases have SQL functions to get the year from a date. Using the ICriteria API, this would look like this:

            var employeesBornIn81 = session.CreateCriteria<Employee>()

                .Add(Restrictions.Eq(Projections.SqlFunction("year", NHibernateUtil.DateTime, Projections.Property("BirthDate")), 1981))

                .List<Employee>();

which adds the following where clause to the SQL statement (on SQL Server 2005):

WHERE datepart(year, this_.BirthDate) = @p0;

8 Responses to “Using SQL Functions in Criteria Restrictions”

  1. Koen Says:

    1981 was a good year…

  2. Davy Brion Says:

    i used to think so ;)

  3. den Ben Says:

    get off my lawn you 2!!

  4. Reflective Perspective - Chris Alcock » The Morning Brew #339 Says:

    [...] Using SQL Functions in Criteria Restrictions – Davy Brion shows how despite the slightly unfriendly syntax it is possible to build criteria based queries in NHibernate that use the the built in functions of the database. [...]

  5. marek Says:

    Hi Davy,

    what if the db doesn’t support the ‘year’ function?
    Doesn’t your code become db-specific when you use this kind of syntax?

    Thanks

  6. Davy Brion Says:

    it’s not entirely db-specific, because these functions are registered per dialect and then map to their DB-specific implementation

    if you use a function that’s only supported by one (or a couple of) dialect, then yes, you lose some db portability.

    you can find the supported functions, and the db-specific implementation they map to, in the constructor of each dialect

  7. pho Says:

    what about functions that need additional parameters, such as DATEPART or SUBSTRING? are those possible?

  8. Davy Brion Says:

    there are some functions that are registered per dialect that support multiple parameters though the way to use them with the Criteria API is probably a bit different… haven’t tried those yet :)

Leave a Reply

XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>