Nhibernate QueryOver JoinAlias UnRelated Entity

2019-02-27 16:24发布

问题:

I have an issue in NHibernate regarding a left join using "JoinAlias" when the result query SQL that I am looking for is this :

"select * from EntityA T1 left join EntityB T2 on T2.EntityAId=T1.id"

And in NHibernate I have this but doesn't work:

 var query = _session.QueryOver(() => EntityA)
                      .Left.JoinAlias(() => EntityA, () => EntityB.EntityA)

In NHibernate EntityA doesn't reference to EntityB but EntityB as a reference to EntityA.

public class EntityA
{ 
   public int Id {get;set;}
}

public class EntityB
{ 
   public int Id {get;set;}
   public EntityA EntityA {get;set;}
}

How can I make this very simple left join in HHibernate Work?

回答1:

This is not possible with Criteria or QueryOver. But we can use HQL, which does support that

  • 14.2. The from clause (small cite and snippet)

Multiple classes may appear, resulting in a cartesian product or "cross" join.

from Formula, Parameter
from Formula as form, Parameter as param

So in the case above we would have HQL like this:

FROM EntityA T1 
   , EntityB T2 
WHEERE T2.EntityAId = T1.id

Almost the same issue

But in case described above, there is reversed relation, already mapped. And that means, that we can extend the C# entity definitions:

public class EntityA
{ 
   public int Id {get;set;}
   // one-to-many
   // the bidirectional mapping of the below relation
   public IList<EntityB> EntityBColl { get; set; }
}

public class EntityB
{ 
   public int Id {get;set;}
   // many-to-one
   // this is the inversed end in fact of the bidirectional mapping
   public EntityA EntityA {get;set;}
}

Having that in place, we can use standard QueryOver API:

// aliases
EntityA EntityA = null;
EntityB EntityB = null;

// query
var query = session.QueryOver(() => EntityA)
    .Left.JoinAlias(() => EntityA.EntityBColl , () => EntityB)
    ...
    ;