C# Datatable 按两个字段分组,将 4 个字段放入数组中

问题描述 投票:0回答:1

我有一个 XLSX 文件,有 4 列(id、表单名称、数据、图像路径)。我的最终目标是根据 id 和表单名称将所有这些行分组为简洁的分组,每个表单包含一组文档。

|ID        | Form     | Date     | ImagePath    |
| -------- | -------- | -------- | ------------ |
|123       | ABC      | 8/1/2023 | c:/pic1.jpg  |
|123       | DEF      | 8/2/2023 | c:/file1.jpg |
|123       | DEF      | 8/2/2023 | c:/file2.jpg |
|123       | DEF      | 8/2/2023 | c:/file3.jpg |
|456       | GHI      | 8/1/2023 | c:/test1.jpg |
|456       | GHI      | 8/1/2023 | c:/test2.jpg |

我想做的是:

|ID        | Form     | Date     | ImagePath    |
| -------- | -------- | -------- | ------------ |
|123       | ABC      | 8/1/2023 | c:/pic1.jpg  |
|123       | DEF      | 8/2/2023 | c:/file1.jpg |
|          |          |          | c:/file2.jpg |
|          |          |          | c:/file3.jpg |
|456       | GHI      | 8/1/2023 | c:/test1.jpg |
|456       |          |          | c:/test2.jpg |

一旦我将其转换为该格式,我就可以迭代它们并对每个 ID 和表单进行一些处理。

我创建了一个类:

public string ID {get; set;}
public string Form {get; set;}
public DateTime docDate {get; set;}
public List<string> files {get; set;)

在我的程序中我尝试过:

Foreach (DataRow row in caseDT.Rows)
{
   for(int i = 0; i < caseDT.Columns.Count; i++)
   {
      // tried multiple if's
   }
}

我想这可以通过 linq 语句来完成,但还没有成功。

var data = caseDT.AsEnumerable();
CaseDoc[] results = data
   .GroupBy(x => new {ID = x.Field<string>("ID"), Form = x.Field<string>("Form")})
   .Select(x => new CaseDoc
    {
       ID = x.key.ID,
       Form = x.key.CaseDoc,
       docDate = // how do I get docdate
       files = // do I do another select here for all the items from image path??
    }

虽然我的测试样本很小,但最终 XLS 的总体大小将为 9000 行。

任何方向将不胜感激。

c# arrays linq types grouping
1个回答
0
投票

首先,我建议您创建一个类来表示 XLSX 文件中的一行。 根据您共享的数据,类似这样的内容将接近所需的内容:

 public class Document
 {
     public string Id {get; set;}
     public string Form {get; set;}
     public DateTime DocumentDate {get; set;}
     public string ImagePath {get; set;)
 }

读取 XLSX 文件并为其中的每一行创建

Document
类的实例后,您可以继续进行如下分组。 我假设您已将所有已解析的行分配到名为
documents
的变量中。

对于要创建的组,您可以定义一个类并将每个组的结果投影到该类中,也可以使用匿名类。 假设您想要使用第一个选项,定义一个类。

public class DocumentsGroup
{
    public string Id { get; set; }
    public string Form { get; set; }

    // Every attribute of the group that is not in the key you use 
    // to create the group could be defined as a List<T>, where
    // T is the corresponding type  

    public List<DateTime> DocumentsDates { get; set; }
    public List<string> ImagesPaths { get; set; }
}

var result = documents.GroupBy(document => new {Id = document.Id, Form = document.Form })
                      .Select(group => new DocumentsGroup 
                      {
                          Id = group.Id,
                          Form = group.Form,
                          DocumentsDates = group.Select(item => item.DocumentDate).ToList()
                          ImagesPaths = group.Select(item => item.ImagePath).ToList()
                      })
                      .ToList();

没有

© www.soinside.com 2019 - 2024. All rights reserved.