c# - 将一对多列表组合成一个平面对象列表 C#
问题描述
所以这是我面临的问题。我有一个一对多的列表关系。以下是列表外观的示例。
列表 1 中的对象是动态的,并且有一些属性,其中最重要的是“id”。第二个列表有一个定义的对象,看起来像“id”“value desc”“actual value”。第二个列表可以有许多行属于第一个列表。“value desc”是属性名称和“实际值”。
我需要将这些列表组合成看起来像这样的东西。具有所有列表 1 属性和第二个列表中所有相应行的对象。如果第二个列表有 3 个项目属于列表 1 中的一个项目,那么新对象应该具有列表 1 的所有属性以及从列表 2 以类似扁平结构的方式收集的所有行。
数据示例
表格1:
ID | 姓名 |
---|---|
1 | 鲍勃 |
2 | 乔 |
表 2
ID | 道具名称 | 价值 |
---|---|---|
1 | 长度 | 2 |
1 | 年龄 | 12 |
1 | 发色 | 蓝色的 |
2 | 长度 | 5 |
2 | 年龄 | 90 |
2 | 发色 | 红色的 |
我希望数据看起来如何
ID | 姓名 | 长度 | 发色 | 年龄 |
---|---|---|---|---|
1 | 鲍勃 | 2 | 蓝色的 | 12 |
2 | 乔 | 5 | 红色的 | 90 |
目前,我有这个工作。
public IEnumerable<dynamic> test(List<dynamic> data, List<modal>
dataset)//closest
{
var query = (from a in data
join b in dataset
on a.id equals b.id into t
select new {
a,
t
});
return query;
}
但是,结果是一个具有列表 1 属性的对象,然后是该对象上的一个属性,该属性是在列表 2 中找到的项目数组。我需要这些项目不在数组中,并且是具有新创建的值的属性名称目的。
我希望我的解释足够清楚!
解决方案
使用数据表:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
DataTable dt1 = new DataTable();
dt1.Columns.Add("id", typeof(int));
dt1.Columns.Add("name", typeof(string));
dt1.Rows.Add(new object[] { 1, "bob" });
dt1.Rows.Add(new object[] { 2, "bob" });
DataTable dt2 = new DataTable();
dt2.Columns.Add("id", typeof(int));
dt2.Columns.Add("propname", typeof(string));
dt2.Columns.Add("value", typeof(object));
dt2.Rows.Add(new object[] { 1, "length", 2 });
dt2.Rows.Add(new object[] { 1, "age", 12 });
dt2.Rows.Add(new object[] { 1, "haircolor", "blue"});
dt2.Rows.Add(new object[] { 2, "length", 5 });
dt2.Rows.Add(new object[] { 2, "age", 90 });
dt2.Rows.Add(new object[] { 2, "haircolor", "red" });
DataTable pivot = new DataTable();
string[] properties = dt2.AsEnumerable().Select(x => x.Field<string>("propname")).Distinct().OrderBy(x => x).ToArray();
pivot.Columns.Add("id", typeof(int));
pivot.Columns.Add("name", typeof(string));
DataColumn[] columns = properties.Select(x => new DataColumn(x, typeof(object))).ToArray();
pivot.Columns.AddRange(columns);
var joins = from id1 in dt1.AsEnumerable()
join id2 in dt2.AsEnumerable() on id1.Field<int>("id") equals id2.Field<int>("id")
select new { id = id1.Field<int>("id"), name = id1.Field<string>("name"), id2 = id2 };
var groups = joins.GroupBy(x => x.id);
foreach (var group in groups)
{
DataRow newRow = pivot.Rows.Add();
newRow["id"] = group.Key;
newRow["name"] = group.First().name;
foreach (var row in group)
{
newRow[row.id2.Field<string>("propname")] = row.id2.Field<object>("value");
}
}
}
}
}
推荐阅读
- c# - 如何将文本块的大小调整为等宽字体和分辨率
- excel - 导出 Datagridview 数据以访问数据库
- docker - 在 Bitbucket Pipeline 中,如何使用新生成的 Docker 镜像动态检测和启动容器
- java - @RequestMapping 和 @PostMapping 有什么区别
- debugging - 如何在 Visual Studio Code 中调试外部库代码?
- python - 导出数据框时如何修复“生成器”对象没有属性“to_csv”
- kubernetes - 如何为 helm 中的子图表引用自定义值文件?
- python - 调试:在哪里可以找到打印功能
- c# - 如何在运行时在 .NET Core 中的模型属性上添加或删除 [RequiredAttribute] 数据注释?
- c++ - 如何理解 C++11 随机数生成器