我有两个表(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,如果该订单存在成功订单。我不确定是否必须使用别名,但到目前为止我所有的尝试都没有成功。
答案 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>();
<强>更新强>
由于您没有Order
到Transaction
的引用,因此您应该还原联接,这样您就可以使用正确的联接来实现此目的。
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
类应包含所有选定的字段。