views:

48

answers:

2

It seems that when using the following NHibernate query, I do not get a root entity when the left outer join has no records.

ICriteria critera = session.CreateCriteria(typeof(Entity));

criteria.CreateCriteria("SubTable.Property", "Property", NHibernate.SqlCommand.JoinType.LeftOuterJoin);

criteria.Add(Expression.Not(Expression.Eq("Property", value)));

The SQL that I am trying to generate is:

SELECT * FROM BaseTable
LEFT JOIN (
    SELECT * FROM SubTable
    WHERE Property <> value
)Sub ON Sub.ForeignKey = BaseTable.PrimaryKey

Notice that the where clause is inside the left join's select statement. That way if there arent any maching sub records, we still get a top level record. It seems like NHibernate is producing the following SQL.

SELECT * FROM BaseTable
LEFT JOIN (
    SELECT * FROM SubTable
)Sub ON Sub.ForeignKey = BaseTable.PrimaryKey
WHERE Sub.Property <> value

Is there anyway to achieve that first piece of SQL? I have already tried:

ICriteria critera = session.CreateCriteria(typeof(Entity));

criteria.CreateCriteria("SubTable.Property", "Property", NHibernate.SqlCommand.JoinType.LeftOuterJoin);

criteria.Add(
    Restrictions.Disjunction()
        .Add(Expression.IsNull("Property"))
        .Add(Expression.Not(Expression.Eq("Property", value)));

I am looking for a solution using the Criteria API.

A: 

I don't use nHibernate but I think this is the SQL you need to generate:

SELECT * 
FROM BaseTable 
LEFT JOIN SubTable sub
 ON Sub.ForeignKey = BaseTable.PrimaryKey and  sub.Property <> value 

What you want isn;t a where clasue but an additional condition on the join. Hope that helps.

HLGEM
very true... I didn't even consider that.
a432511
This explains why: http://wiki.lessthandot.com/index.php/WHERE_conditions_on_a_LEFT_JOIN
HLGEM
I understand the problem, I guess I was looking for how to solve it using the NHibernate Criteria API. Thanks!
a432511
A: 

Try this:

var hql = @"select bt
            from BaseTable bt
                left join bt.SubTable subt
                    with subt.Property <> :property";

Or perhaps:

var hql = @"select bt
            from BaseTable bt
                left join bt.SubTable subt
                    where subt.ForeignKey = bt.PrimaryKey
                        and subt.Property <> :property";

Finally:

var result = session.CreateQuery(hql)
                    .SetParameter("property", "whateverValue")
                    .List<BaseTable>();
Rafael Belliard
Looking to solve this with NHibernate's Criteria API. Thanks
a432511