1

我有一个数据库表,我将其用作报告的来源。表格布局看起来像。表 1 是一个更大的数据库表的子集。但是对于报告我只需要某些列所以我正在使用下面给出的函数创建一个新的数据表

Value  Description   Hours
    1          A           2
    2          B           3
    3          C           5
    1          A           3
    2          B           4
    2          B           3
    3          C           3


private DataTable CreateFocusOfEffortData()
    {
        var dtChartData = new DataTable();
        dtChartData.Columns.Add("Description", typeof(string));
        dtChartData.Columns.Add("Hours", typeof(Double));
        var myDataView = ReportData.DefaultView;
        myDataView.RowFilter = "ActivityUnitID = " + _ActivityUnitID;
        for (var i = 0; i < myDataView.ToTable().Rows.Count; i++)
        {
            var dataRow = new Object[dtChartData.Columns.Count];
            dataRow[0] = ReportData.Rows[i]["Description"];
            dataRow[1] = csaConvert.ToDouble(ReportData.Rows[i]["Hours"]);
            dataRow[2] = ReportData.Rows[i]["Value"];
            dtChartData.Rows.Add(dataRow);
        }
        return dtChartData;
    }

现在我需要用上表中的汇总数据设计另一个报告。此表应基于 Column["Value] 组合所有列的数据。例如,在我的情况下,我们在 Value 列 1、2、3 中有三个不同的值。结果表应该对所有三个值进行小时总和。

    Value   Description  Hours
    1         A           5
    2         B           10
    3         C           8

现在我可以通过创建另一个存储过程在 sql 中执行此操作,但我宁愿使用我现有的数据表并编写一个 C# 函数来获取结果。有没有更简单的方法可以使用 LINQ 实现这一目标?

4

2 回答 2

6

你采取了错误的方法。在 SQL 中完成这项工作。

 SELECT value, description, sum(hours) as hours from tblData group by value, description;

以上将为您提供您在问题中显示的第二个表格。

这样做的原因是,将数据传递给客户端应用程序只是为了将其直接传递回 SQL 会不必要地消耗内存和系统调用。此外,错误、错误、类型转换问题等的空间要小得多。

如果您真的想制作更窄的表格(这通常是一个坏主意),请这样做:

 SELECT value, description, hours from tblData into tblSkinnyData;

一般来说,如果您出于某种原因需要这个瘦表,您会在主表上使用 VIEW。

于 2012-09-23T12:51:27.663 回答
2

您可以使用AsEnumerable()in order 使用 LINQ,然后GroupBy通过ValueandDescription和 do SumonHours为第一行设置:

var result = dtChartData.AsEnumerable()
            .GroupBy(row => new
                {
                    Value = row.Field<int>("Value"),
                    Description = row.Field<string>("Description")
                })
            .Select(g =>
                {
                    var row = g.First();
                    row.SetField("Hours", g.Sum(r => r.Field<double>("Hours")));

                    return row;
                });

结果将返回IEnumerable<DataRow>,但如果您想DataTable返回,请使用:

var resultTable = result.CopyToDataTable();
于 2012-09-23T12:49:55.473 回答