2011-11-29 56 views
0

我努力在nHibernate查询中复制简单的SQL左连接。 SO上的其他答案导致我更加困惑,以解决在域查询中解决左连接问题的最明智的方法。努力在nHibernate查询中加入左连接

例子:

2 DB表:

Customer 
CustId INT PK 

Orders 
OrderId INT PK 
CustId INT FK 
Status INT 

1 SQL查询:

Select c.CustId from Customer c 
left join Orders o on o.CustId = c.CustId and o.Status = 2 
where o.OrderId is null 

这将检索客户的唯一列表中的状态2没有命令谁, 请注意,它还包括根本没有订单的客户。 这是一个人为的例子来简化这个问题,但这种类型的查询是非常有用的,不容易做任何其他方式。

想象一下“顾客”和“订单”的映射,它们仅仅反映了上面的示例表。

是否有一种简单的方法可以在查询中提取nHibernate中唯一的,非状态-2的客户列表,而不诉诸SQL查询或结束于选择n + 1场景?

查询偏好:

1 LINQ到的nhibernate
2 QueryOver
3 HQL
4标准。

谢谢。

回答

2

请参阅http://docs.jboss.org/hibernate/core/3.6/reference/en-US/html/queryhql.html#queryhql-joins。这是Hibernate参考,而不是NHibernate的参考,但我认为他们的工作是相同的(顺便说一句,this post似乎也印证了它):

你可能会提供额外的加入使用HQL与关键字条件。

从猫的猫 左加入cat.kittens如小猫 与kitten.bodyWeight> 10.0

所以,在你的情况下,它应该看起来像

select c.CustId from Customer c 
left join Orders o with o.Status = 2 
+0

谢谢你,我现在已经通过HQL获得了这个工作,尽管它确实依赖于所有正在映射的连接关联 - 我希望创建一个查询来连接不相关的域对象,但我猜测关联映射是有意义的。 – iandayman

+0

是的,映射协会真的很有意义。我认为不做映射它们就可以做你想做的事情。 –

0

如果实体无关并且你不想映射一个关系,你可以使用theta连接。见here

也许像

Select c from Customer c, Order o 
where o.CustId = c.CustId and o.Status = 2 
+0

我想做类似这样的事情,但看不到一种方法可以使用这种连接方式进行左连接查询 – iandayman

+0

啊,很遗憾,您无法按定义完成外连接,因为两个元素都需要满足条件。因此,为了使用HQL,您需要按照isuruceanu的建议来映射关联。 – Vadim

1

NHibernate的3.0具有的ICriteria .CreateAlias的重载方法,它需要4个参数,可以最后一个参数是条款二。

下面是一个例子:

DetachedCriteria criteria = DetachedCriteria.For<Models.BO.Customer>("customer") 
      .CreateAlias(ReflectionHelper.PropertyName<Models.BO.Customer>(x => ((Models.BO.Interfaces.ICustomerQueryOnly) x).Tasks), 
       "activeTasks", JoinType.LeftOuterJoin, Restrictions.IsNotNull("activeTasks.LockedBy") 
      ) 
      .CreateAlias(ReflectionHelper.PropertyName<Models.BO.Customer>(x => ((Models.BO.Interfaces.ICustomerQueryOnly) x).Tasks2), 
       "availableTasks", JoinType.LeftOuterJoin, 
       availableTasksRestraction 
      ) 
      .Add(Restrictions.Eq("CustomerBase", _customerBase)) 
      .Add(Restrictions.Eq("IsActive", true)); 

这endup的东西,如:我需要提取活动任务的所有客户和可用任务数以及各项

 FROM Customers c 
     left join Tasks t on t.customerId = c.Id and (t.DeletedDate is null and 
t.lockedById is null and [etc]) 
     left join Tasks activetasks [etc] 
    where [...] 

在这个例子中顾客。

+0

感谢 - 最终为HQL解决方案大饱眼福,但很高兴知道withClause。 – iandayman