【问题标题】:Calculating the sum of previous rows in a column in a DataTable计算 DataTable 中列中先前行的总和
【发布时间】:2018-12-06 18:18:45
【问题描述】:

我在计算 DataTable 等数据结构中某列中所有先前行的总和时遇到了一些问题

例如,我们有一个表,其中包含 “等待时间”“突发时间” 列。

Waiting Time 的行值必须通过从 Burst Time 列中的前几行获取值来计算(如果有这样的 a.k.a 它不是我们当前计算值的第一行) p>

我怎样才能做到这一点?是否像使用Compute() 并传递适当的过滤字符串一样简单?

编辑:我想做的一个例子。

【问题讨论】:

  • 能否提供一个您已经尝试过的示例?
  • 只是Sum(Burst Time column),但显然这不起作用,因为它汇总了总数,而不仅仅是前几行的值。
  • 再一次,最好看到确切的例子,也许里面有真实的表格和数据,加上你的代码。还有一件事:“前几行”是什么意思?您是否有时间字段或其他可用于创建“先前”逻辑的东西?
  • 我用一个简单的例子来编辑我的原始帖子。第一行的值分别为 2 和 0。下一行的等待时间值是通过将所有前一行的突发时间值相加来计算的。
  • 你的目标很明确,问的是看看你到目前为止做了什么。从那里帮助更容易:)

标签: c# datatable


【解决方案1】:

我做了一个例子。现在知道如何填充 DataTable,这就是我想出硬编码的原因。

public class Program
{
    public static void Main(string[] args)
    {
        dataSet = new DataSet();
        var dataTable = MakeTable();
        var columns = dataTable.Columns;

        Console.WriteLine("Defined Table");
        PrintDataTable(dataTable);

        foreach (DataRow dataTableRow in dataTable.Rows)
        {
            var id = dataTableRow["ID"];
            var burstTime = dataTable.Compute("Sum(BurstTime)", $"ID < {id}");
            dataTableRow["WaitingTime"] = burstTime;
        }

        Console.WriteLine();
        Console.WriteLine("Table After Operation");
        PrintDataTable(dataTable);

        Console.ReadLine();
    }

    private static void PrintDataTable(DataTable dataTable)
    {
        foreach (DataRow dataTableRow in dataTable.Rows)
        {
            Console.WriteLine($"{dataTableRow["Id"]}\t\t| {dataTableRow["WaitingTime"]}\t\t| {dataTableRow["BurstTime"]}");
        }
    }

    private static DataSet dataSet;

    private static DataTable MakeTable()
    {
        // Create a new DataTable.
        DataTable table = new DataTable("childTable");
        DataColumn column;
        DataRow row;

        // Create first column and add to the DataTable.
        column = new DataColumn();
        column.DataType = System.Type.GetType("System.Int32");
        column.ColumnName = "ID";
        column.AutoIncrement = true;
        column.Caption = "ID";
        column.ReadOnly = true;
        column.Unique = true;

        // Add the column to the DataColumnCollection.
        table.Columns.Add(column);

        // Create second column.
        column = new DataColumn();
        column.DataType = System.Type.GetType("System.String");
        column.ColumnName = "ChildItem";
        column.AutoIncrement = false;
        column.Caption = "ChildItem";
        column.ReadOnly = false;
        column.Unique = false;
        table.Columns.Add(column);

        // Create third column.
        column = new DataColumn();
        column.DataType = System.Type.GetType("System.Int32");
        column.ColumnName = "ParentID";
        column.AutoIncrement = false;
        column.Caption = "ParentID";
        column.ReadOnly = false;
        column.Unique = false;
        table.Columns.Add(column);

        // Create third column.
        column = new DataColumn();
        column.DataType = System.Type.GetType("System.Int32");
        column.ColumnName = "WaitingTime";
        column.AutoIncrement = false;
        column.Caption = "WaitingTime";
        column.ReadOnly = false;
        column.Unique = false;
        table.Columns.Add(column);

        // Create fourth column.
        column = new DataColumn();
        column.DataType = System.Type.GetType("System.Int32");
        column.ColumnName = "BurstTime";
        column.AutoIncrement = false;
        column.Caption = "BursTime";
        column.ReadOnly = false;
        column.Unique = false;
        table.Columns.Add(column);

        dataSet.Tables.Add(table);

        // Create three sets of DataRow objects, 
        // five rows each, and add to DataTable.
        for (int i = 0; i <= 4; i++)
        {
            row = table.NewRow();
            row["ID"] = i;
            row["ChildItem"] = "Item " + i;
            row["ParentID"] = 0;
            row["WaitingTime"] = 0;
            row["BurstTime"] = i;
            table.Rows.Add(row);
        }
        for (int i = 0; i <= 4; i++)
        {
            row = table.NewRow();
            row["ID"] = i + 5;
            row["ChildItem"] = "Item " + i;
            row["ParentID"] = 1;
            row["WaitingTime"] = 0;
            row["BurstTime"] = i + 5;
            table.Rows.Add(row);
        }
        for (int i = 0; i <= 4; i++)
        {
            row = table.NewRow();
            row["ID"] = i + 10;
            row["ChildItem"] = "Item " + i;
            row["ParentID"] = 2;
            row["WaitingTime"] = 0;
            row["BurstTime"] = i + 10;
            table.Rows.Add(row);
        }

        return table;
    }
}

我想对你来说最有趣的是:

foreach (DataRow dataTableRow in dataTable.Rows)
{
    var id = dataTableRow["ID"];
    var burstTime = dataTable.Compute("Sum(BurstTime)", $"ID < {id}");
    dataTableRow["WaitingTime"] = burstTime;
}

我认为这里最重要的是你必须想出自己的比较逻辑,即Compute(string, string)函数中的第二个参数。

【讨论】:

  • 谢谢,这正是我从前几行计算的意思!另外,作为C#的初学者,通过filter参数的{}语法发现数据绑定变量是有可能的。
  • @TKD21 其实不是数据绑定。它是一个string interpolation 为过滤器值构建一个字符串。
猜你喜欢
  • 2013-04-17
  • 2016-07-30
  • 1970-01-01
  • 1970-01-01
  • 2021-07-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多