首页 > 解决方案 > 将一对多列表组合成一个平面对象列表 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 中找到的项目数组。我需要这些项目不在数组中,并且是具有新创建的值的属性名称目的。

我希望我的解释足够清楚!

标签: c#listlinq

解决方案


使用数据表:

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");
                }
            }

        }
    }
}

推荐阅读