C# 合并 2 个几乎相同的 JSON 个对象

C# merge 2 almost identical JSON objects


前段时间我做了一个将 JSON 合并在一起的函数。

我有一个看起来像这样的 table,在这个例子中,它是通过在 table 'persons' 上左连接 table 'friends' 制作的:

Id Name FriendName FriendAge
1 Danny Jason 19
1 Danny Cesie 18
2 Jason Danny 19

它会导致 json 对象如下所示:

[
  {
    "Id": 1,
    "Name": "Danny",
    "Friends": [
      {
        "Name": "Jason",
        "Age": 19
      },
      {
        "Name": "Cesie",
        "Age": 18
      }
    ]
  },
  {
    "Id": 2,
    "Name": "Jason",
    "Friends": [
      {
        "Name": "Danny",
        "Age": 19
      }
    ]
  }
]

我使用以下 C# 代码完成此操作:

using System;
using System.Data;
using Newtonsoft.Json;

namespace JsonTest
{
    class Program
    {
        private class Result
        {
            public int Id { get; set; }
            public string Name { get; set; }
            public Friend[] Friends { get; set; }
        }

        private class Friend
        {
            public string Name { get; set; }
            public int Age { get; set; }
        }

        static void Main(string[] args)
        {
            string json = "[{\"Id\":1,\"Name\":\"Danny\",\"FriendName\":\"Jason\",\"FriendAge\":19},{\"Id\":1,\"Name\":\"Danny\",\"FriendName\":\"Cesie\",\"FriendAge\":18},{\"Id\":2,\"Name\":\"Jason\",\"FriendName\":\"Danny\",\"FriendAge\":19}]";
            // Original table from example
            DataTable dt = JsonConvert.DeserializeObject<DataTable>(json);

            // Get distinct values from DataTable
            DataView dv = new DataView(dt);
            DataTable distinct_values = dv.ToTable(true, "Id");

            Result[] result = new Result[distinct_values.Rows.Count];
            int i = 0;
            foreach (DataRow row in distinct_values.Rows)
            {
                // Filter the original table on one Id from the distinct values
                dv.RowFilter = $"Id = {row["Id"]}";
                DataTable temp_dt = dv.ToTable();
                Result temp = new Result();

                // Copy general data over to the temp
                temp.Id = Convert.ToInt32(temp_dt.Rows[0]["Id"].ToString());
                temp.Name = temp_dt.Rows[0]["Name"].ToString();

                Friend[] rows = new Friend[temp_dt.Rows.Count];

                // loop over all the rows and copy the array data over
                int j = 0;
                foreach (DataRow temprow in temp_dt.Rows)
                {
                    rows[j] = new Friend();
                    rows[j].Name = temprow["FriendName"].ToString();
                    rows[j].Age = Convert.ToInt32(temprow["FriendAge"].ToString());
                    j++;
                }

                // Assign everything to where it it supposed to be
                temp.Friends = rows;
                result[i] = temp;
                i++;
            }

            Console.WriteLine(JsonConvert.SerializeObject(result, Formatting.Indented));

            Console.ReadLine();
        }
    }
}

效果很好。但我的问题是,是否有另一种更清洁或更快的方法来完成整个操作?如果是这样,我在哪里可以找到这个?提前致谢。

我会创建一个模型来比使用 DataTable

更容易携带您的数据
public class RequestModel{
    public int Id { get; set; }
    public string Name { get; set; }
    public string FriendName { get; set; }
    public int FriendAge { get; set; }
}

那你可以试试用lambda来做,用GroupBy的方法得到分组Id,Name.

string json = "[{\"Id\":1,\"Name\":\"Danny\",\"FriendName\":\"Jason\",\"FriendAge\":19},{\"Id\":1,\"Name\":\"Danny\",\"FriendName\":\"Cesie\",\"FriendAge\":18},{\"Id\":2,\"Name\":\"Jason\",\"FriendName\":\"Danny\",\"FriendAge\":19}]";
var req = JsonConvert.DeserializeObject<IEnumerable<RequestModel>>(json);
var res= req.GroupBy(x=> new {x.Id,x.Name})
    .Select(x=> new Result{
        Name =x.Key.Name,
        Id = x.Key.Id,
        Friends = x.Select(z=> new Friend(){
            Name = z.FriendName,
            Age =  z.FriendAge
        }).ToArray()
    });
var jsonResult = JsonConvert.SerializeObject(res);