tags:

views:

385

answers:

1

Hello, I have a method that is loading a collection of Products. Each order has a child object called Manufacturer (I have a many-to-one relationship set up in my mapping file). I would like to sort the collection of Products by Products.Manufacturer.Name. How can I do this?

Product mapping:

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
  <class name="Model.Catalog.Product,Model" table="Catalog.Product">
    <id name="ID" column="ID" type="Int32" unsaved-value="0">
      <generator class="native" />
    </id>
    <property name="Name" column="Name" type="string" length="50" not-null="true" />
    <property name="Description" column="Description" type="String" not-null="false" />
    <property name="CreatedByUserId" column="CreatedByUserId" type="Guid" not-null="true" />
    <many-to-one name="Manufacturer" column="ManufacturerID" not-null="true" class="Catalog.Manufacturer,Model" />
   </class>
</hibernate-mapping>

Manufacturer mapping:

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
  <class name="Model.Catalog.Manufacturer,Model" table="Catalog.Manufacturer">
    <id name="ID" column="ID" type="Int32" unsaved-value="0">
      <generator class="native" />
    </id>
    <property name="Name" column="Name" type="string" length="50" not-null="true" />
  </class>
</hibernate-mapping>

Calling code:

public IList<Model.Catalog.Product> GetProducts(int startIndex, int rowCount, string sort, string productNameFilter, int? manufacturerIDFilter)
{
    IList<Model.Catalog.Product> result = null;

    using (ITransaction transaction = this.Session.BeginTransaction())
    {
        ICriteria query = this.Session.CreateCriteria<Model.Catalog.Product>();

        //Add paging...
        query.SetFirstResult(startIndex).SetMaxResults(rowCount);

        //Add filters...
        if (productNameFilter != null)
        {
            query.Add(Expression.Like("Name", productNameFilter, MatchMode.Anywhere));
        }
        if (manufacturerIDFilter.HasValue == true)
        {
            //This works when using Manufacturer.ID...
            query.Add(Expression.Eq("Manufacturer.ID", manufacturerIDFilter.Value));
        }


        //Add sort...
        switch (sort)
        {
            case "ProductName ASC":
                query.AddOrder(new Order("Name", true));
                break;
            case "ManufacturerName ASC":
                //This doesn't work when using Manufacturer.Name, but does when using Manufacturer.ID...
                query.AddOrder(new Order("Manufacturer.Name", true));
                break;
            case "ProductName DESC":
                query.AddOrder(new Order("Name", false));
                break;
            case "ManufacturerName DESC":
                query.AddOrder(new Order("Manufacturer.Name", false));
                break;
        }

        result = query.List<Model.Catalog.Product>();

        transaction.Commit();
    }

    return result;
}
+1  A: 

I think that you will need to use a something like the following.

IList<Order> orders = Session.CreateCriteria(typeof(Order))
  .AddOrder(Order.Asc("Order.Customer.LastName")
  .List<Order>();
Nathan Fisher
Perfect! I am still kind of a noobie and didn't realize you could do that. Thanks a lot!
Mike C.
Sorry I may have spoken too soon. I was able to use certain fields in my child objects, but not all fields.
Mike C.
Updated original post to include mappings and code samples.
Mike C.
The reason that you can sort using ManufacturerID is because it is foriegn key on your product table. If you look a the SQL there will be no join to `Catalog.Manufacturer` you will need to add another `query.CreateCriteria("Manufacturer")` just before the ` query.AddOrder(new Order("Manufacturer.Name", true));`. This is so that nhibernate knows to include the manufacturers table as part of the query
Nathan Fisher
That was it! Thank you very much for the explanation. I am just getting started with NHibernate and learning something new everyday.
Mike C.