【问题标题】:C# - How To Mathematical Operations In DataTableC# - 如何在 DataTable 中进行数学运算
【发布时间】:2019-02-21 01:40:51
【问题描述】:

我有一个 DataTable,我想在将它们添加到 DataGridView 之前进行一些数学运算。第一个,我想找到我的 DataTable 的第三列的最大数量,第二个我想将第三列中的所有值除以这个最大数量。毕竟我想替换我的新值而不是旧值。我的 DataTable 是这样的;

        Column 1     Column 2     Column 3
     ---------------------------------------
          a             b          2000000
          q             r          250000
          s             t          185000
          m             w          400000
          o             p          750000

操作后,我的DataTable应该是这样的;

        Column 1     Column 2     Column 3
     ---------------------------------------
          a             b          1
          q             r          0.125
          s             t          0.0925
          m             w          0.0002
          o             p          0.375

这是我的代码;

      connection.Open();
      //Some insignificant operations here.
      for (int q = 0; q < w.Length; q++)
      {
          for (int a = q + 1; a < w.Length; a++)
          {
              string query = ".....";
              SqlDataAdapter myAdapter = new SqlDataAdapter(query, connection);
              DataTable myTable = new DataTable();
              myAdapter.Fill(myTable);
              //I started here for finding maximum number in DataTable.
              int[] myColumn = dt.AsEnumerable().Select(x => x.Field<int>("Column3")).ToArray();
              int myMaximum = myColumn.Max();
              //I don't know what should I do after that.
              foreach (DataRow myRows in myTable.Rows)
              {
                  //Some significant operations again...
                  dgv1.Rows.Add(...);
              }
          }
      }
      connection.Close();

【问题讨论】:

  • 你有什么问题?
  • 我不知道如何对我的 DataTable 中的所有 Column3 应用这个数学运算,我想在将它们添加到 DataGridView 之前替换我的新值而不是旧值。
  • 您最感兴趣的是如何按照您所描述的方式执行此操作,还是只是想要帮助获得您想要的结果?例如,如果您愿意,您可以执行您在 SQL 语句中描述的数学运算。
  • 我需要 C# 代码。我在SQL语句中试过了,但是不行。

标签: c# math datagridview datatable datarow


【解决方案1】:

我建议摆脱 DataTable 并使用普通的 c# 类。
DataTable 是“重”结构,它做的比你需要的要多得多,在大多数情况下你不需要它.

创建类来表示您的数据

public class Item
{
    public string Column1 { get; set; }
    public string Column2 { get; set; }
    public int Column3 { get; set; }
}

加载数据

public List<Item> LoadData()
{
    var query = "SELECT Column1, Column2, Column3 FROM Table";
    using (var connection = new SqlConnection(connectionString))
    using (var command = connection.CreateCommand())
    {
        command.CommandType = CommandType.Text;
        command.CommandText = query;

        using (var reader = command.ExecuteReader())
        {
            var data = new List<Item>();
            while(reader.Read())
            {
                var item = new Item
                {
                    Column1 = reader.GetString(0),
                    Column1 = reader.GetString(1),
                    Column1 = reader.GetInt32(2)
                };
                data.Add(item);
            }

            return data;
        }
    }
}

创建代表计算数据的类

public class CalculatedItem
{
    public string Column1 { get; }
    public string Column2 { get; }
    public decimal Calculated { get; }

    public CalculatedItem(Item item, decimal maxValue)
    {
        Column1 = item.Column1;
        Column2 = item.Column2;
        Calculated = (decimal)item.Column3 / maxValue
    }
} 

用法

var data = LoadData();
var maxValue = data.Select(item => item.Column3).Max();
var calculatedData = data.Select(item => new CalculatedItem(item, maxValue)).ToList();

// Bind data to the DataGridView
DataGridView1.DataSource = calculatedDate;

【讨论】:

    【解决方案2】:

    试一试:

    var max = myTable.Rows.Cast<DataRow>().Max(r => r.Field<double>("Column 3"));
    
    foreach (var row in myTable.Rows.Cast<DataRow>())
    {
        row["Column 3"] = row.Field<double>("Column 3") / max;
    }
    

    可运行的测试代码:

    var myTable = new DataTable();
    myTable.Columns.Add("Column 3", typeof(double));
    myTable.Rows.Add(20_00_000);
    myTable.Rows.Add(250_000);
    myTable.Rows.Add(185_000);
    myTable.Rows.Add(400_000);
    myTable.Rows.Add(750_000);
    
    Console.WriteLine(String.Join(", ", myTable.Rows.Cast<DataRow>().Select(r => r.Field<double>("Column 3"))));    
    
    var max = myTable.Rows.Cast<DataRow>().Max(r => r.Field<double>("Column 3"));
    
    foreach (var row in myTable.Rows.Cast<DataRow>())
    {
        row["Column 3"] = row.Field<double>("Column 3") / max;
    }
    
    Console.WriteLine(String.Join(", ", myTable.Rows.Cast<DataRow>().Select(r => r.Field<double>("Column 3"))));
    

    这个输出:

    2000000、250000、185000、400000、750000 1、0.125、0.0925、0.2、0.375

    更新基于“第 3 列”是 int。

    Console.WriteLine(String.Join(", ", myTable.Rows.Cast<DataRow>().Select(r => r.Field<int>("Column 3"))));
    
    int max = myTable.Rows.Cast<DataRow>().Max(r => r.Field<int>("Column 3"));
    double[] results = myTable.Rows.Cast<DataRow>().Select(r => (double)r.Field<int>("Column 3") / max).ToArray();
    
    Console.WriteLine(String.Join(", ", results));
    

    现在只需在构建 DataGridView 时索引到 results。

    【讨论】:

    • 我应该将这段代码写在我的 foreach 中还是其他地方?
    • @heyyoucoder - 如果您将其放入您的foreach,您认为会发生什么?
    • 我问它是因为您发送的代码没有更改值。
    • @heyyoucoder - 我在这里的环境中测试它时确实如此。
    • 它说;此行的“System.InvalidCastException:特定转换无效”; var max = myTable.Rows.Cast().Max(r => r.Field("Column 3"));
    【解决方案3】:

    您是否考虑在现有表中添加第 4 列?将该列设为“表达式”列以按照您的描述进行数学运算,然后隐藏第三列?

    下面是一个例子……

    DataTable GridTable;
    
    public Form1() {
      InitializeComponent();
    }
    
    private void Form1_Load(object sender, EventArgs e) {
      GridTable = GetDataTable();
      FillTable(GridTable);
      AddExpressionColumn(GridTable);
      dataGridView1.DataSource = GridTable;
      dataGridView1.Columns["Column3"].Visible = false;
    }
    
    private DataTable GetDataTable() {
      DataTable dt = new DataTable();
      dt.Columns.Add("Column1", typeof(string));
      dt.Columns.Add("Column2", typeof(string));
      dt.Columns.Add("Column3", typeof(int));
      return dt;
    }
    
    private void FillTable(DataTable dt) {
      dt.Rows.Add("a", "b", 2000000);
      dt.Rows.Add("q", "r", 250000);
      dt.Rows.Add("s", "t", 185000);
      dt.Rows.Add("m", "w", 400000);
      dt.Rows.Add("o", "p", 750000);
    }
    
    private void AddExpressionColumn(DataTable dt) {
      DataColumn expCol = new DataColumn("Result", typeof(decimal));
      dt.Columns.Add(expCol);
      string expressionString = "Column3 / " + GetMaxValue(dt).ToString();
      expCol.Expression = expressionString;
    }
    
    private int GetMaxValue(DataTable dt) {
      int max = (int)dt.Compute("Max(Column3)", "");
      if (max == 0)
        return 1;
      return max;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-08-18
      • 2020-02-05
      • 1970-01-01
      • 2011-07-27
      • 2011-09-11
      • 1970-01-01
      相关资源
      最近更新 更多