将键/值对列表转换为数据表



我正在做一个解析器。它从源文本获取值。它事先不知道它将获得多少或哪些值,即变量的名称,它们的计数等可能会有很大的变化。源代码的每个部分只提供一些值,而不是一个完整的列表。这些值当前存储在自定义类的列表中,类似于KeyValuePair,但从头编写。

从源中检索的样本:

Section 1:
    KeyA = ValA1
    KeyB = ValB1
    KeyD = ValD1
Section 2:
    KeyC = ValC2
Section 3:
    KeyB = ValB3
    KeyD = ValD3

等。

现在,我想把这些信息以DataGrid的形式显示给用户:

| KeyA  | KeyB  | KeyC  | KeyD  |
+-------+-------+-------+-------+
| ValA1 | ValB1 |       | ValD1 |
|       |       | ValC2 |       |
|       | ValB3 |       | ValD3 |

目前,我正在遍历每个部分中找到的所有值,检查列是否存在-如果不存在-创建新列。如果列存在-为各自的行/列添加值。然后将结果DataTable附加到DataGrid作为:

dg.ItemSource=dt.AsDataView();

这可以完美地工作,但是,速度太慢了。

我很感激任何关于如何加快速度的想法。初始存储,或转换为DataTable,或以其他方式绑定数据以实现对用户的相同表示。

c#, WPF, .NET framework 4.5

Update:所有的加载和处理都是事先完成的。就绪数据以处理过的部分树的形式存储。作为属性之一的每个节保存一个键/值对列表。每个部分都有一个类来填充给定的DataTable与它的值。

。后端数据如下:

File1
  + Section 1 on level 1
  |   + Section 1
  |   + Section 2
  + Section 2 on level 1
  + Section 3 on level 1
  |   + Section 1
  |   + Section 2
  |   + Section 3
  |   + Section 4
  + Section 4
File2 ...

每个Section有一个方法:

public void CollectValues(DataTable target) {...}

由具有某些数据表的更高级元素调用(最初为空,然后逐渐被填充)。

每个部分包含内部变量:

private List<CustomValue> Values;

保存CustomValue类中所有已经找到和处理过的值。CustomValue ~= KeyValuePair,但增加了处理例程。

所以发生的是CollectValues是从请求的级别(可以是顶部,可以是任何其他)调用空的未准备的数据表。CollectValues迭代(foreach)当前级别列表中的所有可用值,并一次将它们添加到目标DataTable 1,在此之前检查DataColumn是否存在所需的名称(target[value . key]!=null) -并在尝试添加各自的值之前创建列(如果需要)。在元代码:

public void CollectValues(DataTable target)
{
    DataRow dr = target.Rows.Create();
    foreach(var pair in Values)
    {
        if(target[pair.Key]==null) target.Columns.Add(...);
        dr[pair.Key] = pair.Value;
    }
    foreach(var child in Children)
        child.CollectValues(target);
}

为什么这个特定的部分值只是类似例程的一部分。其他例程在相同的数据集上进行类似的爬行,检索其他东西(主要是使用列表,而不是datattables)——所有这些都几乎可以立即完成工作。收集数据表可能需要几秒钟的时间,一个数据源才能填充数据网格。

值的平均数量很少超过1000(例如,10列× 100行)。只有在DataGrid被完全填充后,DataTable才会被附加到DataGrid。

只是关于尺寸的信息:源文件——通常是2到10个文件。每个源文本大小可以在100Kb - 100mb之间。通常文件大小在1-2 MB左右。后端数据在内存中的大小通常在100mb以下。

并再次高亮显示。只有DataTable让我担心。亮点,部分,源检索,过滤等-所有工作在我的期望。所以我首先寻找一种方法来优化从键/值对列表到数据表的转换,或者一种方法来存储这些值不同的初始(处理后),以加快处理。

希望这给了足够的信息。

我将寻找一个数据结构而不是DataTable在这里使用。听起来你需要的是Dictionary<string, Dictionary<int, CustomValue>>string是您的列名,int是数据行的ID, CustomValue是数据本身。

public void CollectValues(Dictionary<string, Dictionary<int, CustomValue>> target)
{
    foreach(var pair in Values)
    {
        if(target[pair.Key]==null) target.Add(new Dictionary<int, CustomValue>());
        target[pair.Key].Add(pair.ID, pair.Value);
    }
    foreach(var child in Children)
        child.CollectValues(target);
}

如果你还没有一个pair.ID,你可以使用一个计数器变量(static或每次调用时传递),这样每个对象都有一个不同的ID。


按行存储值可能更有意义,每组数据都有列,而不是相反。这将是一个IEnumerable<Dictionary<string, CustomValue>>,每个Dictionary代表一行。您可以使用target.Select(x => x.Key).Distinct()拉出所有列。

DataTable是慢的。它能做很多事情。

如果你都是字符串那么我将创建一个集合

List<String> ColNames;
List<String> ColValues;
List<ColValues> RowsColValues;

然后您需要使用ColValues[i]语法手动将列绑定到DataGrid。

为了提高速度,使用listviewgridview。
与Gridview相比,DataGrid速度慢且体积大。
但是GridView不编辑。

这可不是瞎编的
我就是这么做的,但情况不同。
用户选择他们想要看到的列。

DyamicColumns

相关内容

  • 没有找到相关文章

最新更新