加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c# – 将键/值对列表转换为datatable

发布时间:2020-12-15 21:44:49 所属栏目:百科 来源:网络整理
导读:我正在研究解析器.它从源文本中获取值.它事先不知道它将获得多少或哪些值,即变量的名称,它们的数量等可能变化很大.源的每个部分仅提供一些值,而不是完整列表.这些值当前存储在自定义类的列表中,类似于KeyValuePair,但是从头开始编写. 对从源检索的内容进行抽
我正在研究解析器.它从源文本中获取值.它事先不知道它将获得多少或哪些值,即变量的名称,它们的数量等可能变化很大.源的每个部分仅提供一些值,而不是完整列表.这些值当前存储在自定义类的列表中,类似于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

更新:所有加载和处理都是事先完成的.就绪数据存储为已处理部分的树.每个部分作为一个属性包含键/值对的列表.每个部分都有一个类来为给定的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 ...

每个部分都有一个方法:

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

更高级别的元素使用一些DataTable调用它(最初是空的并且随着它的进行填充).

每个部分都包含内部变量:

private List<CustomValue> Values;

其中包含CustomValue类中已找到和已处理的所有值. CustomValue~ = KeyValuePair,但添加了处理例程.

所以会发生什么是CollectValues从请求的级别调用(可能是顶级的,可能是任何其他的),空的未准备好的DataTable. 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);
}

为什么这个特定的部分 – 值只是类似例程的一部分.其他例程在相同的数据集上进行类似的爬行,检索其他内容(主要使用列表,没有DataTables) – 所有这些都在即时工作.虽然收集DataTable可能需要几秒钟才能生成一个源,以便生成DataGrid.

平均值的数量很少超过1000(例如,10列乘100行). DataTable仅在完全填充后才附加到DataGrid.

只是有关尺寸的信息:
来源 – 通常是2到10个文件.每个源文本大小可以是100Kb – 100 MB.通常的文件大小约为1-2 MB.内存中后端数据的大小通常小于100 MB.

并再次强调.只有DataTable让我担心.亮点,分段,源检索,过滤等 – 都符合我的期望.所以我首先要看 – 一种优化从键/值对列表转换到DataTable的方法,或者最初(处理后)以不同方式存储这些值的方法来加速过程.

希望这能提供足够的信息.目前没有列出来源以减小尺寸.

解决方法

我会在这里寻找除DataTable之外的数据结构.听起来像你需要的是Dictionary< string,Dictionary< int,CustomValue>&gt ;.字符串是您的列名,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,则可以使用计数器变量(静态或随每次调用传递),以便每个对象具有不同的ID.

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

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读