Los Techies : Blogs about software and anything tech!

Parameter lists in NHibernate


Occasionally I need to return a set of entites that match a collection of parameters.  In SQL, I would use the "IN" clause, then manually create each parameter in ADO.NET.  With NHibernate, that's not necessary anymore.  NHibernate has built-in capabilities for a collection parameter, creating all the necessary ADO.NET parameters behind the scenes.

For example, suppose my database has the following structure (from Northwind):

What I'm trying to do is to load up all Products for a certain set of Categories.  My Product and Category class are nothing interesting:

public class Category
{
    public int Id { get; set; }
    public string Name { get; set; }
}
public class Product
{
    public int Id { get; set; }
    public string Name { get; set; }
    public Category Category { get; set; }
}

I didn't bother mapping all of the properties, just the ones for the classes defined above.  Here are the mapping files:

<class name="Category" table="Categories">
    <id name="Id" column="CategoryID" type="int">
        <generator class="assigned" />
    </id>
    <property name="Name" not-null="true" column="CategoryName" />
</class>
<class name="Product" table="Products">
    <id name="Id" column="ProductId" type="int">
        <generator class="assigned" />
    </id>
    <property name="Name" not-null="true" column="ProductName" />
    <many-to-one name="Category" column="CategoryID">
    </many-to-one>
</class>

When using plain HQL, I need to use the SetParameterList method on the IQuery object:

[Test]
public void Should_get_products_by_categories_correctly_using_HQL()
{
    ISession session = GetSession();
    string hql = @"from Product p
                   where p.Category in (:categories)";

    var categoriesToSearch = new[] {new Category {Id = 1}, new Category {Id = 2}};

    var query = session.CreateQuery(hql);
    query.SetParameterList("categories", categoriesToSearch);

    var products = query.List<Product>();

    products.Count.ShouldEqual(24);
}

When using the Criteria API, I'll need to use the InExpression:

[Test]
public void Should_get_products_by_categories_correctly_using_criteria()
{
    ISession session = GetSession();
    var criteria = session.CreateCriteria(typeof(Product));

    var categoriesToSearch = new[] {new Category {Id = 1}, new Category {Id = 2}};
    criteria.Add(new InExpression("Category", categoriesToSearch));
    var products = criteria.List<Product>();

    products.Count.ShouldEqual(24);
}

When I execute both of these, NHibernate produces the correct IN expression for each.  Unfortunately, I am ashamed to say I initially tried to create the parameter list myself.  Next time, I'll know better.

Kick It on DotNetKicks.com
Posted Aug 26 2008, 08:39 PM by bogardj
Filed under:

Comments

Ray wrote re: Parameter lists in NHibernate
on 08-27-2008 2:33 AM

Oh boy... Jimmy you not the only one... Thanks for sharing!

Dew Drop - August 27, 2008 | Alvin Ashcraft's Morning Dew wrote Dew Drop - August 27, 2008 | Alvin Ashcraft's Morning Dew
on 08-27-2008 7:47 AM

Pingback from  Dew Drop - August 27, 2008 | Alvin Ashcraft's Morning Dew

Ted wrote re: Parameter lists in NHibernate
on 08-27-2008 8:33 AM

Can you use parameters in an in clause?  Or does it just produce something like:

SELECT * from Products

WHERE CATEGORY IN (1,2)

bogardj wrote re: Parameter lists in NHibernate
on 08-27-2008 10:44 PM

@Ted

No, it creates parameters for each value for you.  I forgot to include the SQL generated in the post.

Nathan wrote re: Parameter lists in NHibernate
on 08-31-2008 2:27 AM

Any idea if there is a LINQ for NH syntax to accomplish the same thing. We're humming along using LINQ but have to drop down to HQL for these pesky IN style queries.

bogardj wrote re: Parameter lists in NHibernate
on 09-01-2008 1:28 PM

@Nathan

Try using the "join" LINQ clause.  I'm not sure if the Linq to NH developers support this use, but I've seen examples for other IQueryProvider implementations.

chris wrote re: Parameter lists in NHibernate
on 01-27-2009 4:08 PM

I hate asking for help on blog posts but this is so close...

From your example above, using the criteria API.  How would I get a list of categories given a list of products.

Thanks for your time!

chris wrote re: Parameter lists in NHibernate
on 01-27-2009 5:44 PM

Figured it out...

needed to add a bag to the Categories

use a CreateCritera and InExpression

Thanks again!

bogardj wrote re: Parameter lists in NHibernate
on 01-27-2009 8:32 PM

@chris

Good, cause I was stumped!

Rich wrote re: Parameter lists in NHibernate
on 11-02-2009 11:20 AM

Just as a heads up, there seems to be some bugs using empty lists and null lists using the SetParameterList.  If you change to use Criteria, then it'll work fine.

Add a Comment

(required)  
(optional)
(required)  
Remember Me?

Enter the numbers above:
Copyright Los Techies 2008, 2009. All rights reserved.
Powered by Community Server (Commercial Edition), by Telligent Systems