子总计关系数据表

时间:2012-04-01 03:05:03

标签: c# linq sum

我有一个关系数据结构的数据表,我需要将子节点总结到它们的父节点一直到顶层父节点(NULL parent Id)

我附上了2张图片,其中显示了原始表格,另一张图片显示了预期结果

original data in datatable

expected results

干杯

1 个答案:

答案 0 :(得分:1)

我采用了一种模拟数据的方法,因为它们本可以通过某些ORM从数据库中实现,即包含数据和子集合的类。加上一些“业务逻辑”来计算所需的数字。因此,您可以选择数据库方法以及内存方法。

在Linqpad:

void Main()
{
    var data = new[]
    { 
        new Record { Id = 1, ParentId = null, Qty = 1, Cost = 0.0m },
        new Record { Id = 2, ParentId = 1, Qty = 2, Cost = 0.0m },
        new Record { Id = 3, ParentId = 1, Qty = 3, Cost = 0.0m },
        new Record { Id = 4, ParentId = 2, Qty = 4, Cost = 0.0m },
        new Record { Id = 5, ParentId = 3, Qty = 5, Cost = 0.0m },
        new Record { Id = 6, ParentId = 2, Qty = 6, Cost = 1.7m },
        new Record { Id = 7, ParentId = 4, Qty = 7, Cost = 1.8m },
        new Record { Id = 8, ParentId = 5, Qty = 8, Cost = 1.9m },
        new Record { Id = 9, ParentId = 5, Qty = 9, Cost = 2.0m },
    }.ToList();

    // Mimic ORM's job:
    data.ForEach(d => d.ChildRecords = 
        data.Where(c => c.ParentId == d.Id).ToList());

    data.Select(d => new { d.Id, d.Cost, d.TotalCost } ).Dump();
}

class Record
{
    public int Id { get; set; }
    public int? ParentId { get; set; }
    public int Qty { get; set; }

    private decimal _cost = 0m;
    public decimal Cost
    {
        get { return this._cost + this.ChildRecords.Sum(cr => cr.TotalCost); }
        set { this._cost = value; }
    }

    public decimal TotalCost
    { 
        get { return this.Qty * this.Cost; }
    }

    public ICollection<Record> ChildRecords;
}

结果:

Id  Cost    TotalCost
1   619.2   619.2
2   60.6    121.2
3   166     498
4   12.6    50.4
5   33.2    166
6   1.7     10.2
7   1.8     12.6
8   1.9     15.2
9   2       18

优化可能是应用一些memoization,即让Cost属性将其getter的结果存储在私有成员变量中。