当B未映射到A或C时,如何使用Hibernate QueryOver或HQL连接3个表(A,B,C)

时间:2013-07-09 19:49:20

标签: hibernate nhibernate fluent-nhibernate nhibernate-mapping queryover

我有3个班级(A,B,C),其中A是多对多的B和C是1到多个B,但B不知道A或C.

A * ---> * B 1< --- * C

映射具有以下内容:(除A,B,C映射外,其他详细信息已删除)

public A()
{
  Id(x => x.Id).Column("idA").GeneratedBy.Identity();
  HasManyToMany(x => x.B)
  .Schema("foo")
  .Table("JoinTableAB")
  .ForeignKeyConstraintNames("FKname", "FK")
  .ChildKeyColumn("idB")
  .ParentKeyColumn("idA")
  .Cascade.None(); 
}

public B()
{
  Id(x => x.Id).Column("idB").GeneratedBy.Identity();
  //nothing mapped to A or C
}

public C()
{
  Id(x => x.Id).Column("idC").GeneratedBy.Identity();
  References(x => x.B).Column("idB")
}

我已经尝试过QueryOver和HQL,但由于它们是基于路径的,因此无法弄清楚如何将3连接在一起。我可以让A和B加入(使用inner.Join a.b),因为A包含B,但由于B不知道C,我无法弄清楚如何在查询中加入它。我尝试将C加入B然后在where子查询中使用A,但由于B是A中的集合,因此我无法获得“ON”条件b.id = a.id工作。

我的返回数据实际上是来自表D,E,F的数据,这些数据最终映射到C(作为父级),但在链的下方。我无法到达D,E,F因为我无法通过C.

在SQL中我可以使用连接表AB和C连接到B来完成它。

select * 
from A a
  join AB ab on ab.idA = a.idA
  join B b on b.idB = ab.idB
  join C c on c.idB = b.idB
where a.idA = 1 

如果我尝试使用QueryOver:

var subquery = QueryOver.Of<A>()
  .Select(a => a.Id)
  .Where(a => a.Id == x)
  .Inner.JoinQueryOver(a => a.BSets, () => B)
  .Inner.JoinQueryOver(m => C.B, () => C);  //2 compilation errors: 
                //1: Arguments cannot be inferred from usage
                //2: Cannot convert B to C 

如果我尝试:

var subquery = QueryOver.Of<A>()
  .Select(a => a.Id)
  .Where(a => a.Id == x)
  .Inner.JoinQueryOver(a => a.BSets, () => B)
  .Inner.JoinQueryOver(b => b.C, () => C) //b.C is not mapped

如果我尝试使用HQL,我有同样的问题:

IQuery hql = Session.CreateQuery(
  "SELECT a.Id " +
  "FROM A a" +
  "INNER JOIN a.BSets b " +
  "INNER JOIN c.B c " +   //does not work.
  "WHERE a.Id = :x")
  .SetParameter("x", id);
  .List();

如果我使用以下内容进行编译但不起作用,因为我们没有使用正确的属性进行加入。

IQuery hql = Session.CreateQuery(
  "SELECT a FROM " +
  "A a, " +
  "B b, " +
  "C c" +
  "WHERE a.Id = b.Id " +  //a.Id does not equal b.Id so returns zero records
  "   AND c.Id = b.Id" +  //c.Id does not equal b.Id so returns zero records
  "   AND a.Id = :x")
  .SetParameter("x", id);

在where子句中我想要的是:

WHERE a.B.Id = b.Id
  AND c.B.Id = b.Id 

但是我无法弄清楚如何编写相应的a.B.Id和c.B.Id。

任何帮助或指示将不胜感激。

0 个答案:

没有答案