tags:

views:

32

answers:

1

I'm hoping to display a list of all of the products ordered. I can display this using the following sql statement

select products.Id,count(products.Id), products.Name from Products
inner join orderitems on Products.Id = orderItems.ProductId
left join orders on orderItems.OrderId = orders.Id
where orders.CompanyId = 27
group by products.Id,products.Name

I have the following entities Order, OrderItem, Product which have foreign key relationships.

I have created the following projection class

public class OrderProduct
{
    public int Id { get; set; } // removed virtual
    public string Name { get; set; } // removed virtual
    public int Quantity { get; set; } // removed virtual
}

Anyway, just hoping someone could kick start how i should approach this query with criteria api or hql

update

following rafaels example i have simplified the hql to

 var hql = @"select p.Id, p.Name, count(p.Id) as Quantity 
            from OrderItem oi 
                inner join oi.Product p on p.Id = oi.Product.Id 
                group by p.Id, p.Name";

this returns the following sql

select product1_.Id as col_0_0_, product1_.Name as col_1_0_, count(product1_.Id) as col_2_0_ from OrderItems orderitem0_ inner join Products product1_ on orderitem0_.ProductId=product1_.Id

which is very close, however it seems to ignore the group by giving me the following error

Column 'Products.Id' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.

orderItem

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
                   assembly="EStore.Domain"
                   namespace="EStore.Domain.Model">

  <class name="OrderItem" table="OrderItems">
    <id name="Id" type="Int32" column="Id" unsaved-value="0">
      <generator class="identity"/>
    </id>
    <property name="Name" column="Name"/>
    <set name="OrderItemAddresses" table="OrderItemAddress" generic="true" cascade="all-delete-orphan"  inverse="true" >
      <key column="OrderItemId" not-null="true" />
      <one-to-many class="EStore.Domain.Model.OrderItemAddress, EStore.Domain" />
    </set>
    <many-to-one name="Product" column="ProductId"  not-null="true" class="EStore.Domain.Model.Product, EStore.Domain" />
    <many-to-one name="Order" column="OrderId"  not-null="true" class="EStore.Domain.Model.Order, EStore.Domain" />
  </class>
</hibernate-mapping>

## product ##

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
                   assembly="EStore.Domain"
                   namespace="EStore.Domain.Model">

  <class name="Product" table="Products">
    <id name="Id" type="Int32" column="Id" unsaved-value="0">
      <generator class="identity"/>
    </id>

    <property name="MinQuantity" column="MinQuantity" type="Int32" not-null="true" />
    <property name="MaxQuantity" column="MaxQuantity" type="Int32" not-null="true" />
    <property name="Name" column="Name" />

  </class>
</hibernate-mapping>
+1  A: 

Try this:

var hql = @"select p.Id, p.Name, count(p.Id) as Quantity 
            from OrderItem oi 
               inner join oi.Products p where p.Id = oi.Product.Id 
               left  join oi.Order o where o.Id = oi.Order.Id 
                 with o.Company.Id = :companyId 
            group by p.Id, p.Name";


var result = session.CreateQuery(hql)
     .SetParameter("companyId", 27)
     .SetResultTransformer(Transformers.AliasToBean(typeof(OrderProduct)))
     .List<OrderProduct>();

Note: If the query fails, do try and instead of with o.Company...


Rafael Belliard
great thanks, wondering if you have any thoughts why the group by is not coming thru. See "update" above.
frosty
@frosty: can you try this query -> http://www.codepaste.net/83cx7b ... ?
Rafael Belliard
i tried that query and i now get "Could not find a setter for property '0' in class 'EStore.Domain.Projection.OrderProduct'". Do i need an hbm file for OrderProduct. See above for my OrderProduct class. If i go need an hbm file what would i put for the quantity property
frosty
@frosty you don't need an HBM for your bulk class. Now, could you try 1) changing the result type to simply List() and see if the list of objects returned correctly? (so we can isolate a query problem from a transformation one) ; 2) could you update to show your mappings and/or classes? This is fishy...
Rafael Belliard
1) change to list(), and works as intended i get a list that contains 3 elements (int, string, int)2) adding hbm above.
frosty
Interesting... think I've never had this one before. Can you check in your profiler/logger if the SQL for the count(*) has been assigned the name 'Quantity'? I'm thinking its NH renaming the variables to some of its' crazyness. http://www.codepaste.net/ygqnmj
Rafael Belliard