如何在子组

时间:2016-03-17 23:54:57

标签: c# mysql linq group-by entity-framework-5

也许我说这一切都错了,我是Linq的新手,但如果有人可以帮助我,我真的很感激。以下是我的代码。我正在尝试在标题和详细信息表中对信息进行总结。因此,我可以看到每个商家位置的总销售额和总访问次数(单个交易)。详细信息表将标题表中的1个事务分成多行,因此1个事务ID可以在详细信息表中多次出现。

            var query2 = db.sales_transaction_header
                           .Join(db.sales_transaction_detail,
                                 sth => sth.transaction_id,
                                 std => std.transaction_id,
                                 (sth, std) => new { TransHeader = sth, TransDetail = std })
                       .GroupBy(x => x.TransHeader.merchant_location_id)
                       .Select(g => new MerchantConsumerSalesDTO
                       {
                           TotalSales = g.Sum(x => x.TransDetail.transaction_amount),
                           MerchantId = g.FirstOrDefault().TransHeader.merchant_location_id,
                           TotalVisits = g.GroupBy(x => x.TransHeader.transaction_id).Select(g2 => g2.Count()),
                       })
                       .ToList();

TotalVisits给了我各种各样的问题!我最初尝试过

TotalVisits = g.Select(x => x.TransHeader.transaction_id).Distinct().Count()

但这给了我一个莫名其妙的错误:

  

'where子句'

中的未知列'Project3.merchant_location_id'

没有.Distinct(),它会正确返回Count(),除非是错误的数字!因为我只需要计算不同的值,但是使用Distinct()它会给我一个错误!所以我尝试在子组上使用GroupBy。这甚至不允许我编译。我得到各种错误,例如“不能隐式地将Ienumerable转换为int”或“无法将匿名类型转换为int” - 我在我的智慧结束!我是完全走错了轨道还是这个小而简单的东西?

提前致谢!

修改 也许这有助于澄清我的意图。我的表格结构如下:

sales_transaction_header
    transaction_id
    merchant_location_id
    card
    transaction_date

sales_transaction_detail
    transaction_detail_id
    transaction_id
    transaction_amount
    seat_nbr

因此,基本上可以根据seat_nbr将单个事务分解为多个详细信息行。因此,如果我理解正确的话,第一个groupby应该只对商家ID进行分组,仍然为个别交易留下多行。我需要另一组来计算唯一的事务ID。正确的吗?

此外,我生成的查询如下:

SELECT `Project2`.`merchant_location_id`, 
       `Project2`.`c1`, 
       `Project2`.`merchant_location_id1`, 
       (SELECT Count(1) AS `A1` 
        FROM   (SELECT DISTINCT `Extent7`.`transaction_id` 
                FROM   `sales_transaction_header` AS `Extent7` 
                       INNER JOIN `sales_transaction_detail` AS `Extent8` 
                               ON `Extent7`.`transaction_id` = 
                                  `Extent8`.`transaction_id` 
                WHERE  `Project2`.`merchant_location_id` = 
                       `Extent7`.`merchant_location_id`) AS 
               `Distinct2`) AS `C2` 
FROM   (SELECT `Apply1`.`merchant_location_id`, 
               `Apply1`.`merchant_location_id` 
                      AS `merchant_location_id1`, 
               (SELECT Sum(`Extent6`.`transaction_amount`) AS `A1` 
                FROM   `sales_transaction_header` AS `Extent5` 
                       INNER JOIN `sales_transaction_detail` AS `Extent6` 
                               ON `Extent5`.`transaction_id` = 
                                  `Extent6`.`transaction_id` 
                WHERE  `Apply1`.`merchant_location_id` = 
                       `Extent5`.`merchant_location_id`) AS 
               `C1` 
        FROM   (SELECT `Distinct1`.`merchant_location_id`, 
                       (SELECT `Extent3`.`transaction_id` 
                        FROM   `sales_transaction_header` AS `Extent3` 
                               INNER JOIN `sales_transaction_detail` AS 
                                          `Extent4` 
                                       ON `Extent3`.`transaction_id` = 
                                          `Extent4`.`transaction_id` 
                        WHERE  `Distinct1`.`merchant_location_id` = 
                               `Extent3`.`merchant_location_id` 
                        LIMIT  1) AS `transaction_id`, 
                       (SELECT `Extent3`.`merchant_location_id` 
                        FROM   `sales_transaction_header` AS `Extent3` 
                               INNER JOIN `sales_transaction_detail` AS 
                                          `Extent4` 
                                       ON `Extent3`.`transaction_id` = 
                                          `Extent4`.`transaction_id` 
                        WHERE  `Distinct1`.`merchant_location_id` = 
                               `Extent3`.`merchant_location_id` 
                        LIMIT  1) AS `MERCHANT_LOCATION_ID1`, 
                       (SELECT `Extent3`.`transaction_date` 
                        FROM   `sales_transaction_header` AS `Extent3` 
                               INNER JOIN `sales_transaction_detail` AS 
                                          `Extent4` 
                                       ON `Extent3`.`transaction_id` = 
                                          `Extent4`.`transaction_id` 
                        WHERE  `Distinct1`.`merchant_location_id` = 
                               `Extent3`.`merchant_location_id` 
                        LIMIT  1) AS `transaction_date`, 
                       (SELECT `Extent3`.`post_date` 
                        FROM   `sales_transaction_header` AS `Extent3` 
                               INNER JOIN `sales_transaction_detail` AS 
                                          `Extent4` 
                                       ON `Extent3`.`transaction_id` = 
                                          `Extent4`.`transaction_id` 
                        WHERE  `Distinct1`.`merchant_location_id` = 
                               `Extent3`.`merchant_location_id` 
                        LIMIT  1) AS `post_date`, 
                       (SELECT `Extent3`.`card_token` 
                        FROM   `sales_transaction_header` AS `Extent3` 
                               INNER JOIN `sales_transaction_detail` AS 
                                          `Extent4` 
                                       ON `Extent3`.`transaction_id` = 
                                          `Extent4`.`transaction_id` 
                        WHERE  `Distinct1`.`merchant_location_id` = 
                               `Extent3`.`merchant_location_id` 
                        LIMIT  1) AS `card_token`, 
                       (SELECT `Extent3`.`transaction_type` 
                        FROM   `sales_transaction_header` AS `Extent3` 
                               INNER JOIN `sales_transaction_detail` AS 
                                          `Extent4` 
                                       ON `Extent3`.`transaction_id` = 
                                          `Extent4`.`transaction_id` 
                        WHERE  `Distinct1`.`merchant_location_id` = 
                               `Extent3`.`merchant_location_id` 
                        LIMIT  1) AS `transaction_type`, 
                       (SELECT `Extent3`.`processed` 
                        FROM   `sales_transaction_header` AS `Extent3` 
                               INNER JOIN `sales_transaction_detail` AS 
                                          `Extent4` 
                                       ON `Extent3`.`transaction_id` = 
                                          `Extent4`.`transaction_id` 
                        WHERE  `Distinct1`.`merchant_location_id` = 
                               `Extent3`.`merchant_location_id` 
                        LIMIT  1) AS `processed`, 
                       (SELECT `Extent3`.`partner_transaction_id` 
                        FROM   `sales_transaction_header` AS `Extent3` 
                               INNER JOIN `sales_transaction_detail` AS 
                                          `Extent4` 
                                       ON `Extent3`.`transaction_id` = 
                                          `Extent4`.`transaction_id` 
                        WHERE  `Distinct1`.`merchant_location_id` = 
                               `Extent3`.`merchant_location_id` 
                        LIMIT  1) AS `partner_transaction_id`, 
                       (SELECT `Extent4`.`transaction_detail_id` 
                        FROM   `sales_transaction_header` AS `Extent3` 
                               INNER JOIN `sales_transaction_detail` AS 
                                          `Extent4` 
                                       ON `Extent3`.`transaction_id` = 
                                          `Extent4`.`transaction_id` 
                        WHERE  `Distinct1`.`merchant_location_id` = 
                               `Extent3`.`merchant_location_id` 
                        LIMIT  1) AS `transaction_detail_id`, 
                       (SELECT `Extent4`.`transaction_id` AS `TRANSACTION_ID1` 
                        FROM   `sales_transaction_header` AS `Extent3` 
                               INNER JOIN `sales_transaction_detail` AS 
                                          `Extent4` 
                                       ON `Extent3`.`transaction_id` = 
                                          `Extent4`.`transaction_id` 
                        WHERE  `Distinct1`.`merchant_location_id` = 
                               `Extent3`.`merchant_location_id` 
                        LIMIT  1) AS `TRANSACTION_ID1`, 
                       (SELECT `Extent4`.`transaction_amount` 
                        FROM   `sales_transaction_header` AS `Extent3` 
                               INNER JOIN `sales_transaction_detail` AS 
                                          `Extent4` 
                                       ON `Extent3`.`transaction_id` = 
                                          `Extent4`.`transaction_id` 
                        WHERE  `Distinct1`.`merchant_location_id` = 
                               `Extent3`.`merchant_location_id` 
                        LIMIT  1) AS `transaction_amount`, 
                       (SELECT `Extent4`.`charity_location_id` 
                        FROM   `sales_transaction_header` AS `Extent3` 
                               INNER JOIN `sales_transaction_detail` AS 
                                          `Extent4` 
                                       ON `Extent3`.`transaction_id` = 
                                          `Extent4`.`transaction_id` 
                        WHERE  `Distinct1`.`merchant_location_id` = 
                               `Extent3`.`merchant_location_id` 
                        LIMIT  1) AS `charity_location_id`, 
                       (SELECT `Extent4`.`event_type_id` 
                        FROM   `sales_transaction_header` AS `Extent3` 
                               INNER JOIN `sales_transaction_detail` AS 
                                          `Extent4` 
                                       ON `Extent3`.`transaction_id` = 
                                          `Extent4`.`transaction_id` 
                        WHERE  `Distinct1`.`merchant_location_id` = 
                               `Extent3`.`merchant_location_id` 
                        LIMIT  1) AS `event_type_id` 
                FROM   (SELECT DISTINCT `Extent1`.`merchant_location_id` 
                        FROM   `sales_transaction_header` AS `Extent1` 
                               INNER JOIN `sales_transaction_detail` AS 
                                          `Extent2` 
                                       ON `Extent1`.`transaction_id` = 
                                          `Extent2`.`transaction_id`) AS 
                       `Distinct1`) AS `Apply1`) AS `Project2` 

更新

最终,我选择了:

         var query = db.sales_transaction_header
                       .Join(db.sales_transaction_detail,
                             sth => sth.transaction_id,
                             std => std.transaction_id,
                             (sth, std) => new { TransHeader = sth, TransDetail = std })
                   .GroupBy(x => x.TransHeader.merchant_location_id)
                   .ToList()
                   .Select(g => new MerchantConsumerSalesDTO
                   {
                       TotalSales = g.Sum(x => x.TransDetail.transaction_amount),
                       MerchantId = g.Key,
                       TotalConsumerVisits = g.GroupBy(x => x.TransHeader.transaction_id).Count(),
                   });

这是由于我正在使用的MySql数据库的限制 - 它在MSSQL中工作很好,显然无需使用ToList(),但至少它现在正在工作!非常感谢,ROB!

1 个答案:

答案 0 :(得分:0)

chat进行讨论后,结果表明该行为是由于MySql连接器中的错误造成的。

以下代码通过评估内存中的组来解决此错误:

var query = db.sales_transaction_header
    .Join(db.sales_transaction_detail,
        sth => sth.transaction_id,
        std => std.transaction_id,
        (sth, std) => new {TransHeader = sth, TransDetail = std})
    .GroupBy(x => x.TransHeader.merchant_location_id)
    .ToList()
    .Select(g => new MerchantConsumerSalesDTO
    {
        TotalSales = g.Sum(x => x.TransDetail.transaction_amount),
        MerchantId = g.Key,
        TotalConsumerVisits = g.GroupBy(x => x.TransHeader.transaction_id).Count(),
    });

这是因为它生成以下代码:

SELECT `GroupBy1`.`k1`      AS `merchant_location_id`, 
       `GroupBy1`.`a1`      AS `C1`, 
       (SELECT Count(1) AS `A1` 
        FROM   (SELECT DISTINCT `Extent3`.`transaction_id` 
                FROM   `sales_transaction_header` AS `Extent3` 
                       INNER JOIN `sales_transaction_detail` AS `Extent4` 
                               ON `Extent3`.`transaction_id` = 
                                  `Extent4`.`transaction_id` 
                WHERE  `GroupBy1`.`k1` = `Extent3`.`merchant_location_id`) AS 
               `Distinct1`) AS `C2` 
FROM   (SELECT `Extent1`.`merchant_location_id`    AS `K1`, 
               Sum(`Extent2`.`transaction_amount`) AS `A1` 
        FROM   `sales_transaction_header` AS `Extent1` 
               INNER JOIN `sales_transaction_detail` AS `Extent2` 
                       ON `Extent1`.`transaction_id` = 
                          `Extent2`.`transaction_id` 
        GROUP  BY `Extent1`.`merchant_location_id`) AS `GroupBy1` 

在MySql中,内部选择不能引用外部结果,所以这一行:

`GroupBy1`.`k1` = `Extent3`.`merchant_location_id`

失败,因为GroupBy1超出了选择范围。

修复是在组后添加ToList(),以便最终选择(和总结)在内存中完成