读取 DataTable 并重新排列它,同时有效地更改时间戳列

埃洛伊·桑切斯

首先,我是第一次在这里提问,希望我的解释足够好。

我必须从数据库中读取具有以下格式的表:

身份信号 价值 小时 分钟 第二 毫秒
1 50.4 2021年 06 21 13 25 34 751
2 71.0 2021年 06 21 13 25 34 764
3 21.3 2021年 06 21 13 25 34 783

并将其更改为如下所示的表:

时间戳 1 2 3
2021/06/21 13:25:34.7 50.4 71.0 21.3

我开发了一个功能代码,但速度太慢(我已经能够减少执行时间,之前它更糟,但现在我卡住了):

using (SqlConnection connection = new SqlConnection(connString))
            {
                connection.Open();
                SqlCommand command = new SqlCommand(queryString, connection);
                if ((int)connection.State == 1)
                {
                    MessageBox.Show("Connection opened!");
                }
                else
                {
                    MessageBox.Show("Something went wrong openning the connection! " + connection.State.ToString());
                }

                SqlDataAdapter da = new SqlDataAdapter(command);
                da.Fill(valueTable);
                foreach (DataRow row in valueTable.Rows)
                {
                    DateTime timestamp = new DateTime(row.Field<int>("Year"),
                        row.Field<int>("Month"),
                        row.Field<int>("Day"),
                        row.Field<int>("Hour"),
                        row.Field<int>("Minute"),
                        row.Field<int>("Second"),
                        row.Field<int>("Millisecond"));

                    string idSignal = row.Field<int>("IdSignal").ToString();
                    double value = row.Field<double>("Value");

                    try
                    {
                        if (finalTable.Select().Last().Field<String>("Timestamp") == timestamp.ToString("MM/dd/yyyy HH:mm:ss.f"))
                        {
                            finalTable.Select().Last()[idSignalNames[idSignal]] = value;
                        }
                        else
                        {
                            DataRow tempRow = finalTable.NewRow();

                            tempRow["Timestamp"] = timestamp.ToString("MM/dd/yyyy HH:mm:ss.f");

                            tempRow[idSignalNames[idSignal]] = value;
                            finalTable.Rows.Add(tempRow);
                        }
                    }
                    catch (Exception ex)
                    {
                        DataRow tempRow = finalTable.NewRow();

                        tempRow["Timestamp"] = timestamp.ToString("MM/dd/yyyy HH:mm:ss.f");

                        tempRow[idSignalNames[idSignal]] = value;
                        finalTable.Rows.Add(tempRow);
                        //System.Console.WriteLine("The first row has been added to finalTable");
                    }

现在,经过的时间是 3.5 秒

谢谢!

编辑 1

你能用文字描述你在那里想要达到的目标吗?该结果表中的第 1,2 和 3 列是什么?— 蒂姆·施梅尔特

第一个表,来自 DB 的表,每个 IdSignal 都有一行,总共有 9 个 IdSignal。该表有超过 20k 行,每个 IdSignal 重复测量,即 1,2,3,4,5,6,7,8,9,1,2,3,4 等。每组测量都在相同的范围内第二个的小数部分,即 1 --> 13:25:34.7xx, 2-->13:25:34.7xx,当它从 IdSignal 1 再次开始时,它是在 13:25:34.8xx 等等。

我的目的是改变它,并为每个信号(1、2、3 等)设置一列,并为每个十进制秒设置一行。

蒂姆·施梅尔特

撇开您可能能够更有效地在数据库中执行此操作的可能性,如果您想在内存中执行此操作,您可以使用以下方法优化可读性和性能:

var timeGroups = valueTable.AsEnumerable()
    .Select(GetRowInfo)
    .GroupBy(x => x.Time)
    .ToList();
            
DataTable finalTable = new DataTable();
finalTable.Columns.Add("Timestamp", typeof(DateTime));
int maxColumn = timeGroups.Max(g => g.Count());
for(int i = 1; i <= maxColumn; i++)
    finalTable.Columns.Add(i.ToString(), typeof(double));

foreach(var grp in timeGroups)
{
    DataRow addedRow = finalTable.Rows.Add();
    addedRow.SetField("Timestamp", grp.Key);
    int col = 0;
    foreach(var row in grp)
    {
        addedRow.SetField((++col).ToString(), row.Value);
    }
}

(DataRow Row, DateTime Time, string IdSignal, double Value) GetRowInfo(DataRow r)
{
    DateTime time = new DateTime(r.Field<int>("Year"), r.Field<int>("Month"), r.Field<int>("Day"), r.Field<int>("Hour"), r.Field<int>("Minute"), r.Field<int>("Second"), r.Field<int>("Millisecond"));
    string idSignal = r.Field<int>("IdSignal").ToString();
    double value = r.Field<double>("Value");
    return (r, time, idSignal, value);
}

除了填充源表的 Ado.Net 部分之外,这将替换您的整个代码。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

重新排列读取

如何有效地同时从两个BLE设备读取温度?

如何使用AsynchronousFileChannel有效地读取StringBuffer

C ++-有效地顺序读取文件

使用第一行的列标题将.txt文件内容读取到DataTable

编辑列引发“无法读取未定义的属性'$ sum'”,Webix DataTable和Firebase

DataTable通过在列中从左到右读取来对数字进行排序

c#将.csv文件读取到具有重复列名的DataTable中

如何读取JSON文件并重新排列代码

DataTable-无法读取null的属性“长度”

读取.txt文件的前10行,并将它们打印在具有固定列数C#的DataTable中

有效地重新排列多维数组的列

读取,选择和重新排列Pandas中的列

使用datatable读取大尺寸csv文件的错误提示

jQuery dataTable错误无法读取未定义的属性“ mData”

使用 FileHelpers 将动态 CSV 读取到 DataTable

如何将文本文件读取到DataTable

无法读取未定义的Google图表的属性“ DataTable”

无法读取未定义的ngx-datatable的属性“索引”

JQuery Datatable错误“无法读取未定义的属性'length'”

Pytables有效地读取和处理数千个组

Java Spring:如何有效地从CSV文件读取和保存大量数据?

如何有效地从控制台读取一行用户输入?

有效地读取大型文本文件

如何有效地读取不断增长的大型文件

如何有效地在多线程程序中读取共享数据?

如何有效地从 JS ArrayBuffer 读取结构(浏览器)?

如何有效地从Cassandra读取数百万行?

findAndModify是否有效地锁定了文档以防止读取冲突?