如何使用 LINQ 在 C# 中重构对象?

How to restructure an Object in C# using LINQ?

我有一个数据集如下:

[
    {
        "Id": 1,
        "Country": "Uruguay",
        "Name": "Foo",
        "Status": "Completed",
    },
    {
        "Id": 2,
        "Country": "Uruguay",
        "Name": "Foo",
        "Status": "Completed",
    },
    {
        "Id": 3,
        "Country": "Germany",
        "Name": "Foo",
        "Status": "Completed",
    },
]

我想按国家对其进行转换和排序,使其如下所示:

[
    {
        "Country": "Uruguay",
        "Details": [
         {
            "Id": 1,
            "Name": "Foo",
            "Status": "Completed",
         },
         {
            "Id": 2,
            "Name": "Foo",
            "Status": "Completed",
         },
        ],
    },
    {
        "Country": "Germany",
        "Details": [
         {
            "Id": 3,
            "Name": "Foo",
            "Status": "Completed",
         },
        ],
    },
],

这些是 C# 中的 类:

public class Countries {
    public int Id { get; set; }
    public string Country { get; set; }
    public string Name { get; set; }
    public string Status { get; set; }
}

public class Details {
    public int Id { get; set; }
    public string Name { get; set; }
    public string Status { get; set; }
}

public class CountryList {
    public string Country { get; set; }
    public List<Details> Details { get; set; }
}

我尝试过的一些方法如下所示:

var foo = countries
    .GroupBy(x => new Details { Id = x.Id, Name = x.Name, Status = x.Status })
    .Select( y => new CountryList 
     {
         // Country = y.Key. 
     }

var foo = countries
    .GroupBy(x => x.Country)
    .Select( y => new CountryList 
     {
         // Country = y.Key.
         Details = y.GroupBy(a => new Details 
         { 
            Id = a.Id, 
            Name = a.Name, 
            Status = a.Status  
         }).ToList() 
     }

我不知道如何使用 LINQ 来解决这个问题。我过去做过一些 GroupBy 操作,但我无法解决这个问题。如何将我的数据集转换为所需的结果?

你不需要第二个 GroupBy

var foo = countries
    .GroupBy(x => x.Country)
    .Select(y => new CountryList 
     {
         Country = y.Key,
         Details = y.Select(a => new Details 
         { 
            Id = a.Id, 
            Name = a.Name, 
            Status = a.Status  
         }).ToList() 
     };

您可以利用 .GroupBy() overload that lets you define a resultSelector 创建您的 CountryList 并填充他们的 Details:

var countries = new List<Countries>
{
    new() { Id = 1, Country = "Uruguay", Name = "Foo", Status = "Completed" },
    new() { Id = 2, Country = "Uruguay", Name = "Foo", Status = "Completed" },
    new() { Id = 3, Country = "Germany", Name = "Foo", Status = "Completed" },
};

List<CountryList> countryList = countries
    .GroupBy(
        c => c.Country,
        ( country, matches ) => new CountryList()
            {
                Country = country,
                Details = matches.Select(match => new Details 
                    { 
                        Id = match.Id, 
                        Name = match.Name, 
                        Status = match.Status 
                    }).ToList()
            })
    .ToList();

( country, matches ) => new CountryList() { ... }resultSelector


示例 fiddle here.

试试这个

var orig = JsonConvert.DeserializeObject<List<Countries>>(json); 

List<CountryList> countries = orig.GroupBy(o => o.Country)
.Select(x => new CountryList {
Country = x.Key,
Details = x.Select(o => new Details {Id=o.Id,Name=o.Name,Status=o.Status} ).ToList()
}).ToList();