Question

I'm reasonably new to nHibernate and I've been trying to write a query. I cant seem to get it right. I have in my model, a "Product" which contains a ICollection of "Component". I need to find all products that contain any components that have a component reference starting with the letter "G". I have tried this:

var matching = session.QueryOver<Product>()
   .JoinQueryOver<Component>(p => p.Components)
   .Where(c => c.ComponentReference.StartsWith("G")).List();

However I am getting a compile error saying 'Delegate System.Func>> does not take 1 parameter.

There is an overload on JoinQueryOver where I can pass in an Expression>>

So I would have thought my query would work since ICollection implements IEnumerable.

I have tried various other ways using .Cast and JoinAlias but they just seem unecessarily complicated.

Can anyone point out where I am going wrong?

Thanks in advance

Was it helpful?

Solution

I would suggest to use the subquery, in this case. It could look like this

Product product = null;
Component component = null;

// the subselect, returning the Product.ID
// only if the Component.ComponentReference is like G%
var subQuery = QueryOver.Of<Component>(() => component)
    .WhereRestrictionOn(() => component.ComponentReference)
        .IsLike("G", MatchMode.Start)
    .Select(c => c.Product.ID);

// the root Product
var query = session.QueryOver<Product>(() => product)
    .WithSubquery
    .WhereProperty(() => product.ID) 
    .In(subQuery);

// and finally the list
var list = query
    .List<Product>();

The resulting SQL would be like this:

SELECT product
FROM product
WHERE productId IN (SELECT ProductId FROM Component WHERE ComponenentReferece LIKE 'G%')

And why to use subquery instead of JOIN? because the join would in this case result in Carthesian product. The set of products returned would be multiplied by all the components starting with G%

The subquery, will result in pure, flat set of Products, so we can correctly use paging over it (.Take() .Skip())

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top