Returning Generic Lists from NHibernate

This was an "aha" moment for me this morning as I was building a small spike project to figure out how we can incorporate NHibernate as our data access layer and still be a happy loosely coupled Smart Client.

Beyond the fact that I have to create a class library to hold all my interfaces for my domain (as I need to inject my data provider into the domain repository and can't have circular references to NHibernate, but that's another story) I was finding it frustrating that I was getting ArrayLists back from NHibernate.

Here's a method that gets me back a list of customer objects from the NHibernate session:

    1 public List<ICustomer> GetCustomers()

    2 {

    3     List<ICustomer> customers = new List<ICustomer>();

    4     ITransaction tx = null;

    5 

    6     try

    7     {

    8         tx = Session.BeginTransaction();

    9         customers = (List<ICustomer>)Session.CreateCriteria(typeof(ICustomer)).List();

   10     }

   11     catch (HibernateException)

   12     {

   13         if (null != tx)

   14         {

   15             tx.Rollback();

   16         }

   17     }

   18 

   19     return customers;

   20 }

Typical stuff and the example you see everywhere. However I like dealing with a generic List<ICustomer> object rather than an IList (some will argue it's the same thing). The code above compiles fine, but when you run it you get an error as it cannot convert an ArrayList to a List<ICustomer> no matter how hard it tries. A quick check on the Session class in Reflector revealed to me there was a generic List<T> method. One line of code change was all that was needed and voila:

    1 public List<ICustomer> GetCustomers()

    2 {

    3     List<ICustomer> customers = new List<ICustomer>();

    4     ITransaction tx = null;

    5 

    6     try

    7     {

    8         tx = Session.BeginTransaction();

    9         customers = (List<ICustomer>) Session.CreateCriteria(typeof (ICustomer)).List<ICustomer>();

   10     }

   11     catch(HibernateException)

   12     {

   13         if(null != tx)

   14         {

   15             tx.Rollback();

   16         }

   17     }

   18 

   19     return customers;

   20 }

Subtle but the change in liine 9 from List() to List<ICustomer)() gets me a collection of List<ICustomer> objects coming back from NHibernate. Silly I know, but something to watch out for as all the examples out there say call List() to get an IList back but this way you can get a generic list of whatever objects you want.

kick it on DotNetKicks.com
Published Monday, March 26, 2007 7:41 AM by Bil Simser
Filed under: ,

Comments

# re: Returning Generic Lists from NHibernate

Tuesday, March 27, 2007 4:18 PM by James Curran

customers = (List<ICustomer>) Session.CreateCriteria(typeof (ICustomer)).List<ICustomer>();

Egads that an ugly line.  Let's see if we can fix it up a bit:

List<T> GetList<T>()

{

return (List<T>) Session.CreateCriteria(typeof(T)).List<T>();

}

// :

// :

List<ICustomer> customers = new List<ICustomer>();

// :

customer = GetList<ICustomer>();

And if you don't like specifying the type explictly:

void FillList<T>(out List<T> list)

{

list = (List<T>) Session.CreateCriteria(typeof(T)).List<T>();

}

// :

// :

List<ICustomer> customers = new List<ICustomer>();

// :

FillList(out customers);

# re: Returning Generic Lists from NHibernate

Friday, March 30, 2007 10:29 AM by alvar

You would hardly miss it, when using intellisense.