尝试使用投影创建多对多关系的QueryOver

时间:2012-07-22 13:44:13

标签: nhibernate many-to-many queryover nhibernate-projections

我有两个表(Orders,Transactions)和一个TransactionsOrders查找表,它只保留OrderId和TransactionsId列。

如果交易失败(n)次,订单可能会有多个交易。 Order对象不知道事务。

我相信我需要使用投影,因为我需要返回所有订单属性以及来自Transactions表(Amount和TransactionDate)的两个属性,如果存在成功的交易记录订购。下面是将生成正确输出的SQL。

   SELECT o.*, ct.TransactionDate, ct.Amount from Orders o
   LEFT OUTER JOIN 
     (SELECT * FROM CreditTransactionsOrders cto
          INNER JOIN CreditTransactions ct 
      ON ct.Id = cto.CreditTransactionId
      WHERE ct.Successful = 1) as ct 
   ON o.Id = ct.OrderId

我试图尝试创建此QueryOver并从Order对象和Transaction对象中投射我需要的属性,但无法正确转换此SQL查询。

最终结果是我需要返回所有订单,并且我需要从Transaction对象返回Amount和Date,如果该订单存在成功订单。我不确定是否必须使用别名,但到目前为止我所有的尝试都没有成功。

1 个答案:

答案 0 :(得分:2)

首先,您必须将SQL重写为更多NHibernate友好状态:

SELECT o.*, ct.TransactionDate, ct.Amount from Orders o
  LEFT OUTER JOIN CreditTransactionsOrders cto 
    ON o.Id = cto.OrderId
  LEFT OUTER JOIN CreditTransactions ct 
    ON ct.Id = cto.CreditTransactionId AND ct.Successful = 1

此SQL将产生与原始查询相同的结果。

在NHibernate中,其他连接标准可以翻译为with语句。

所以你可以使用重载接受withClause参数。因此,假设您将Orders和CreditTransactions映射为多对多。你应该得到以下QueryOver。

Order o = null;
CreditTransaction ct = null;

var orders = session.QueryOver(() => o)
    .Left.JoinAlias(x => x.Transactions, () => ct, () => ct.Successful == 1)
    .List<Order>();

<强>更新

由于您没有OrderTransaction的引用,因此您应该还原联接,这样您就可以使用正确的联接来实现此目的。

Order o = null;
CreditTransaction ct = null;

var orders = session.QueryOver(() => ct)
    .Right.JoinAlias(x => x.Orders, () => o, () => ct.Successful == 1)
    .Select(
        x => x.TransactionDate,
        x => x.Amount,
        x => o.Id // other Order fields
    ).TransformUsing(Transformers.AliasToBean<TransactionsDto>())
    .List<TransactionsDto>();

TransactionsDto类应包含所有选定的字段。