使用NHibernate进行原始SQL查询的Custom Transformer

时间:2016-10-26 21:55:28

标签: c# mysql nhibernate

我有customerorders的表格与purchases的表格相关联。每个订单都可以进行多次购买,这很奇特,但想象一下,就好像您在结账时分别为每件商品付款一样。每个订单都有一个客户名称和日期,每次购买都有付款类型和总额。

我有一个漂亮的查询,让您了解客户的名称,您可以找到他们最新的独特购买类型。

例如: 客户A共计3个订单,2个通过信用卡,1个通过现金。

我问数据库"按A付款方式的最新独特订单是什么?"数据库返回2个结果 - 最近的信用卡订单& 1现金订单。

这是查询:

String sqlQueryStr = $@"SELECT ee.PaymentType, ee.Total
FROM
(
            SELECT e.CustomerName, ee.PaymentType, ee.Total, MAX(e.Date) as MaxTimestamp
                FROM customerorders ee
                INNER JOIN purchases e ON e.Id=ee.OrderId WHERE CustomerName='{customerName}'
                GROUP BY 1, 2, 3
) AS sub
INNER JOIN purchases e ON e.Date = sub.MaxTimestamp AND e.CustomerName = sub.CustomerName
INNER JOIN customerorders ee ON ee.OrderId=e.Id AND ee.PaymentType = sub.PaymentType;"

ISQLQuery query = session.CreateSQLQuery(sqlQueryStr);
return query.SetResultTransformer(new AliasToBeanResultTransformer(typeof(Purchase)))
            .List<Purchase>();

这本身很有效。客户A的结果如下,我有我想要的东西:

  1. &#39; PaymentType:信用总额:100&#39;
  2. &#39; PaymentType:现金总额:50&#39;
  3. 但是,现在我想做一些我不提供“客户名称”的事情。我想以同样的方式获得每个人的

    现在,如果您回想起我之前所说的内容,Purchase没有CustomerName。所以我不能删除WHERE并再使用变压器了!

    当我删除&#39; WHERE&#39;并为e.CustomerName添加一个额外的SELECT,我使用查询在MySQL中获得此输出:

    1. &#39;客户名称:付款类型:信用总额:100&#39;
    2. &#39;客户名称:付款方式:现金总额:50&#39;
    3. &#39;客户名称:B PaymentType:信用总额:20&#39;
    4. &#39;客户名称:C PaymentType:信用总额:15&#39;
    5. 我正在考虑制作定制变压器,但我不确定哪种变压器可以让我处理这种结果。它现在不只是一个Purchase,它也有名字。我可能希望它们组合在一起(而不是在不同的行上)?

1 个答案:

答案 0 :(得分:0)

public sealed class CustomTransformer: IResultTransformer
    {
        public IList TransformList(IList collection)
        {
            return collection;
        }

        public object TransformTuple(object[] tuple, string[] aliases)
        {
            return new UniqueCustomerPurchase()
            {
                   CustomerName = (string)tuple[0],
                   PaymentType = (string)tuple[1],
                   Total = (uint)tuple[2]
            };
        }
    }

这就是我现在所拥有的。这似乎运作良好,但是,我希望有一种方法可以将CustomerName分组到Purchases列表(paymentType&amp; total),而不必执行此操作。我最终不得不第二次迭代集合,将它们分组:

ISQLQuery query = session.CreateSQLQuery(sqlQueryStr);
return query.SetResultTransformer(new CustomTransformer())
            .List<UniqueCustomerPurchase>()
            .GroupBy(cp => cp.CustomerName)
            .Select(g => new KeyValuePair(g.Key, g.Select(cp => cp));