Dashboard > ActiveRecord > ... > Documentation > Using HQL
Using HQL
Added by Daniel Rothmaler, last edited by Daniel Rothmaler on Aug 20, 2007  (view change)
Labels: 
(None)


Using HQL

For a reference of the HQL language, please check: http://www.hibernate.org/hib_docs/reference/en/html/queryhql.html

For documentation about the unreleased (svn) version of this feature, check: Using HQL - Unreleased.

There are three ways to use direct HQL queries from within ActiveRecord.

SimpleQuery and ScalarQuery

SimpleQuery and ScalarQuery can be used in cases where the query would be a direct HQL query call, with no complex parameter handling.

Here's some samples:

[ActiveRecord]
public class Blog : ActiveRecordBase
{
    ...

    // static method from Blog class, retrieves all Post instances
    // from the blog of the specified author.
    public static Post[] GetPostsFromAuthor( String author )
    {
       SimpleQuery q = new SimpleQuery(typeof(Post), @"
         from Post p
         where p.Blog.Author = ?
       ", author);
       return (Post[]) ExecuteQuery(q);
    }

    // static method from Blog class, retrieves the ID of all Post instances
    // in a specified date interval
    public static int[] GetPostIdsFromInterval( DateTime start, DateTime end )
    {
       // the second type parameter specifies the type of the query result
       SimpleQuery q = new SimpleQuery(typeof(Post), typeof(int), @"
          select p.ID
          from Post p
          where p.Date between ? and ?
       ", start, end);
       return (int[]) ExecuteQuery(q);
    }

    // instance method from Blog, gets the last post date
    public DateTime LastPostDate()
    {
       ScalarQuery q = new ScalarQuery(typeof(Post), @"
          select max(p.Date)
          from Post p
          where p.Blog = ?
       ", this);
       return (DateTime) ExecuteQuery(q);
    }
}

Custom Query

If you want:

  • custom parameter handling;
  • custom SQL queries (not HQL);
  • direct use of NHibernate's Criteria; or
  • direct access to NHibernate's ISession or IQuery objects;

Then you can write a custom ActiveRecord query.

You just need to inherit from ActiveRecordBaseQuery (or implement the IActiveRecordQuery interface).

Some samples:

public class QueryWithNamedParameters : ActiveRecordBaseQuery
{
   public String AuthorName = null;
   public int MaxResults = 2;

   public QueryWithNamedParameters()
     : base(typeof(Blog))
   {
   }

   public override void Execute(ISession session)
   {
      String hql = "from Blog b";

      if (AuthorName != null)
        hql += " where b.Author = :author";

      IQuery q = session.CreateQuery(hql);

      if (AuthorName != null)
        q.SetString("authorName", AuthorName);

      q.SetMaxResults(MaxResults);

      return base.GetResultsArray(typeof(Blog), q.List(), null, false);
   }
}

The usage:

[ActiveRecord]
public class Blog : ActiveRecordBase
{
   ...

   public Blog[] GetThreeBlogsFromAuthor( String authorName )
   {
      QueryWithNamedParameters q = new QueryWithNamedParameters();
      q.AuthorName = authorName;
      q.MaxResults = 3;
      return (Blog[]) ExecuteQuery(q);
   }
}

TODO: sample of custom query using NHibernate's CreateCriteria() and CreateSQLQuery().

Execute Callback

The third way to write custom queries is to use the Execute method, which basically does the same as the Custom Query approach, but without the need to write any additional classes.

[ActiveRecord]
public class Blog : ActiveRecordBase
{
    ...

    public static Post[] GetPostsFromAuthor( String author )
    {
       return (Post[]) Execute( new NHibernateDelegate(GetPostsFromAuthorCallback), author );
    }

    private static object GetPostsFromAuthorCallback( ISession session, object instance )
    {
        // create the query...
        IQuery query = session.CreateQuery( "from Post p where p.Blog.Author = :author" );

        // set the parameters...
        query.SetString("author", (String) instance);

        // fetch the results...
        IList results = query.List();

        // OPTIONAL: convert the results to an array or
        // something meaningful, instead of returning the IList
        Post[] posts = new Post[results.Count];
        results.CopyTo(posts, 0);

        // return
        return posts;
    }
}
Using HQL - Unreleased (ActiveRecord)

Site running on a free Atlassian Confluence Community License granted to Castle Project. Evaluate Confluence today.
Powered by Atlassian Confluence, the Enterprise Wiki. (Version: 2.5.4 Build:#809 Jun 12, 2007) - Bug/feature request - Contact Administrators