【问题标题】:Combine one to many lists into one flat list of objects C#将一对多列表组合成一个平面对象列表 C#
【发布时间】:2021-02-12 08:53:01
【问题描述】:

这就是我面临的问题。我有一个一对多的列表关系。 以下是列表外观的示例。

列表 1 中的对象是动态的,并且具有一些属性,其中最重要的是“id”。 第二个列表有一个定义的对象,看起来像这样“id”“value desc”“actual value”。 第二个列表可以有许多行属于第一个列表。 “value desc”是属性名称和“实际值”。

我需要将这些列表组合成如下所示的内容。具有所有列表 1 属性和第二个列表中所有对应行的对象。如果第二个列表有 3 个项目属于列表 1 中的一个项目,那么新对象应该具有列表 1 的所有属性以及从列表 2 以类似扁平结构的方式收集的所有行。

数据示例

表 1:

id name
1 bob
2 joe

表 2

id propname value
1 length 2
1 age 12
1 haircolor blue
2 length 5
2 age 90
2 haircolor red

我希望数据的外观

id name length haircolor age
1 bob 2 blue 12
2 joe 5 red 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 中的一个项目数组。我需要这些项目不在一个数组中,并且是具有值的属性名称新创建的对象。

希望我的解释足够清楚!

【问题讨论】:

  • 您能提供一些示例输入和输出数据吗?
  • 当然,看到这张图片ibb.co/B2DJm2P 我认为这将有助于加载。如您所见,返回查询 var 具有第一个列表中对象的属性和第二个列表中的对象数组。我需要的是第二个列表的所有属性都不在数组中。原因是我在系统的其他地方进行了一些处理。我基本上只想直接循环通过查询而不使用子循环来访问数组中的对象。这有意义吗?
  • 将使用表格形式(不是图像)的输入和输出数据更新问题。有关详细信息,请参阅此链接 - meta.stackoverflow.com/questions/277716/…
  • 已完成,希望对您有所帮助
  • 如果您为不同的 ID 设置不同的属性集,您会期待什么结果?

标签: c# list linq


【解决方案1】:

使用数据表:

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

        }
    }
}

【讨论】:

  • 感谢您的建议。这里唯一的限制是我需要事先了解属性名称。不幸的是,就我而言,我没有这些知识。因为第二个列表中的潜在属性列表可以是在用户级别定义的任何内容。我相信你可以在这里开始看到我的困境xD。编辑。没关系,我看到我实际上可以在第二个表上动态创建属性。我会玩弄你的解决方案!我会告诉你进展如何。
  • 唯一需要的两个属性名称是 id 和名称。使用以下方法找到属性名称: string[] properties = dt2.AsEnumerable().Select(x => x.Field("propname")).Distinct().OrderBy(x => x).ToArray ();
猜你喜欢
  • 2020-03-04
  • 1970-01-01
  • 1970-01-01
  • 2017-04-12
  • 2021-03-28
  • 1970-01-01
  • 2020-06-01
  • 2015-09-04
  • 1970-01-01
相关资源
最近更新 更多