我有一个 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 行。
任何方向将不胜感激。
最佳答案
首先,我建议您创建一个类来表示 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(gr => new DocumentsGroup
{
Id = gr.Id,
Form = gr.Form,
DocumentsDates = gr.Select(item => item.DocumentDate)
.ToList()
ImagesPaths = gr.Select(item => item.ImagePath)
.ToList()
})
.ToList();
注意:如果您还希望 DocumentDate
成为分组的一部分 - 我不确定 100%,无论您是否想要这个 -,那么 a) 您只需更改 DocumentsGroup
-请检查那里的注释 -,&b) 在用于分组的键中也包含此属性。
关于C# Datatable 按两个字段分组,将 4 个字段放入数组中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/76980116/