1

我有一个 DataTable 我想按摩成一种新格式(这是附加到 gridview 时的结果):

 <table cellspacing="0" rules="all" border="1" id="GridView1" style="border-collapse: collapse;">
        <tr>
            <th scope="col">
                Line
            </th>
            <th scope="col">
                StartTime
            </th>
            <th scope="col">
                EndTime
            </th>
            <th scope="col">
                Attribute
            </th>
            <th scope="col">
                Value
            </th>
        </tr>
        <tr>
            <td>
                Line1
            </td>
            <td>
                24/01/2013 7:30:10 AM
            </td>
            <td>
                24/01/2013 8:00:10 AM
            </td>
            <td>
                Actual
            </td>
            <td>
                0
            </td>
        </tr>
        <tr>
            <td>
                Line1
            </td>
            <td>
                24/01/2013 7:30:10 AM
            </td>
            <td>
                24/01/2013 8:00:10 AM
            </td>
            <td>
                ProductCategory
            </td>
            <td>
                FFAC
            </td>
        </tr>
        <tr>
            <td>
                Line1
            </td>
            <td>
                24/01/2013 7:30:10 AM
            </td>
            <td>
                24/01/2013 8:00:10 AM
            </td>
            <td>
                Target
            </td>
            <td>
                36.5
            </td>
        </tr>
        <tr>
            <td>
                Line2
            </td>
            <td>
                24/01/2013 7:26:50 AM
            </td>
            <td>
                24/01/2013 8:00:10 AM
            </td>
            <td>
                Actual
            </td>
            <td>
                69
            </td>
        </tr>
        <tr>
            <td>
                Line2
            </td>
            <td>
                24/01/2013 7:26:50 AM
            </td>
            <td>
                24/01/2013 8:00:10 AM
            </td>
            <td>
                ProductCategory
            </td>
            <td>
                FFAC
            </td>
        </tr>
        <tr>
            <td>
                Line2
            </td>
            <td>
                24/01/2013 7:26:50 AM
            </td>
            <td>
                24/01/2013 8:00:10 AM
            </td>
            <td>
                Target
            </td>
            <td>
                55.5555582046509
            </td>
        </tr>
        <tr>
            <td>
                Line3
            </td>
            <td>
                24/01/2013 8:00:20 AM
            </td>
            <td>
                24/01/2013 8:47:50 AM
            </td>
            <td>
                Actual
            </td>
            <td>
                1475
            </td>
        </tr>
        <tr>
            <td>
                Line3
            </td>
            <td>
                24/01/2013 8:00:20 AM
            </td>
            <td>
                24/01/2013 8:47:50 AM
            </td>
            <td>
                ProductCategory
            </td>
            <td>
                FFAC
            </td>
        </tr>
        <tr>
            <td>
                Line3
            </td>
            <td>
                24/01/2013 8:00:20 AM
            </td>
            <td>
                24/01/2013 8:47:50 AM
            </td>
            <td>
                Target
            </td>
            <td>
                202.430557310581
            </td>
        </tr>
        <tr>
            <td>
                Line4
            </td>
            <td>
                24/01/2013 7:31:30 AM
            </td>
            <td>
                24/01/2013 8:00:10 AM
            </td>
            <td>
                Actual
            </td>
            <td>
                1384
            </td>
        </tr>
        <tr>
            <td>
                Line4
            </td>
            <td>
                24/01/2013 7:31:30 AM
            </td>
            <td>
                24/01/2013 8:00:10 AM
            </td>
            <td>
                ProductCategory
            </td>
            <td>
                FFAC
            </td>
        </tr>
        <tr>
            <td>
                Line4
            </td>
            <td>
                24/01/2013 7:31:30 AM
            </td>
            <td>
                24/01/2013 8:00:10 AM
            </td>
            <td>
                Target
            </td>
            <td>
                3179.26381587982
            </td>
        </tr>
        <tr>
            <td>
                Line5
            </td>
            <td>
                24/01/2013 7:37:00 AM
            </td>
            <td>
                24/01/2013 8:00:10 AM
            </td>
            <td>
                Actual
            </td>
            <td>
                0
            </td>
        </tr>
        <tr>
            <td>
                Line5
            </td>
            <td>
                24/01/2013 7:37:00 AM
            </td>
            <td>
                24/01/2013 8:00:10 AM
            </td>
            <td>
                ProductCategory
            </td>
            <td>
                FHHT
            </td>
        </tr>
        <tr>
            <td>
                Line5
            </td>
            <td>
                24/01/2013 7:37:00 AM
            </td>
            <td>
                24/01/2013 8:00:10 AM
            </td>
            <td>
                Target
            </td>
            <td>
                92.6652171770756
            </td>
        </tr>
        <tr>
            <td>
                P2_Bundler
            </td>
            <td>
                24/01/2013 7:35:00 AM
            </td>
            <td>
                24/01/2013 8:00:10 AM
            </td>
            <td>
                Actual
            </td>
            <td>
                7
            </td>
        </tr>
    </table>

我知道如果记录具有相同的行、开始和结束时间,则记录是相关的。

我想要做的是获得按 ProductCategory 分组的实际值和目标值的总和。换句话说:

ProductCategory | Sum(Actual) | Sum(Target)

FFAC            | 1000        | 2000

FHHT            | 200         | 175

任何指导将不胜感激!

问候,

克里斯

4

2 回答 2

2

你不会在这里做任何按摩;)

dataTable 的结构将比网格代码更有用,但要从 DataTable 中获得所需的内容,您应该这样做。

var result = myDataTable.AsEnumerable()
              .GroupBy(m => m.Field<string>("ProductCategory"))
              .Select(g => new {
                  productCategory = g.Key,
                  sumActual = g.Sum(x => x.Field<decimal>("Actual")),
                  sumTarget = g.Sum(x => x.Field<decimal>("Target"))
               });
于 2013-01-24T15:34:55.540 回答
0

哎,我以为这会比预期的更难,但最终变得更容易了,我重写了这个。您在线上执行分组,但随后您只需查询每个组中的行以获取 ProductCategory。

首先,您将按主键分组,在这种情况下,我认为是Line列。所以:

myDataTable.AsEnumerable()
    .GroupBy(m => m.Field<string>("Line"))

接下来,我们将不得不为这些分组中的每一个找到类别。由于每个分组都是一个IEnumerable<T>,因此只需Select在过滤我们的Attributeas后执行 aProductCategory并获得第一个值。ProductCategory通过考虑不存在属性的情况,我使用了一点“防御性”编码:

    ...
    .Select(g => new 
        { 
            ProductCategory = g.Where(r => r.Field<string>("Attribute") == "ProductCategory")
                        .Select(r => r.Field<string>("Value"))
                        .FirstOrDefault() ?? "No Category",
            SumActual = g.Sum(x => x.Field<decimal>("Actual")),
            SumTarget = g.Sum(x => x.Field<decimal>("Target"))
        })

编辑:好的,现在我明白你在说什么了。我最初的想法是正确的,因为您将每个原始组(基于 Line)分组为更多组。确实没有简单的方法,而且选项也不漂亮。事实上,您必须对每个组进行分组,但是为了对组进行分组,您必须在组中查询单个实体,然后基于另外 2 个实体进行聚合(这使得在这里使用 LINQ 非常困难)。

myDataTable.AsEnumerable()
    .GroupBy(m => m.Field<string>("Line"))
    .Select(g => new
        {
            ProductCategory = g.Where(r => r.Field<string>("Attribute") == "ProductCategory")
                        .Select(r => r.Field<string>("Value"))
                        .FirstOrDefault() ?? "No Category",
            Actual = g.Where(r => r.Field<string>("Attribute") == "Actual")
                        .Select(r => 
                            { 
                                decimal d = 0m; 
                                Decimal.TryParse(r.Field<string>("Value"), out d);
                                return d;
                            }
                        .FirstOrDefault(),
            Target = g.Where(r => r.Field<string>("Attribute") == "Target")
                        .Select(r => 
                            { 
                                decimal d = 0m; 
                                Decimal.TryParse(r.Field<string>("Value"), out d);
                                return d;
                            }
                        .FirstOrDefault()
        })
    .GroupBy(n => n.ProductCategory)
    .Select(g => new
        {
            ProductCategory = g.Key,
            SumActual = g.Sum(x => x.Actual),
            SumTarget = g.Sum(x => x.Target)
        })

同样,不是很漂亮......特别是因为您的“值”列是字符串,您必须解析它们才能获得有意义的值(在这种情况下,求和一个数字)。这里的前提是您将所有记录分组为“块”,然后将这些块组合成单个匿名对象。因此,每个匿名对象代表特定行的所有数据行属性/值对。从那里,您只需根据所需的键(在本例中为 ProductCategory)进行分组,并执行所需的聚合。

PS,我实际上会使用 PIVOT 在数据库端执行此查询。可能需要更多设置,但随后您为设计用于执行此类数据处理/聚合的系统提供它可以处理的工作,并为更重要的事情保留前端 CPU 周期。

于 2013-01-24T19:00:39.533 回答