Использование LINQ для выравнивания вложенной структуры

#c# #linq

#c# #linq

Вопрос:

Я получаю полезную нагрузку JSON, которая содержит вложенные списки. Можно ли использовать LINQ для выравнивания структуры и извлечения вложенных списков в денормализованную форму?

У меня сильный опыт работы с базой данных, поэтому я называю это денормализованной формой данных JSON.

Я использовал LINQ раньше, но не использовал эти структуры глубокого типа.

Я пытался использовать метод LINQ fluent, но, похоже, я не могу добраться до вложенных списков

 
        public class Exampleobject
        {
            public string result { get; set; }
            public Propertydata propertyData { get; set; }
        }

        public class Propertydata
        {
            public List<Buildings> building { get; set; }           
        }



        public class Buildings
        {
            public string itemId { get; set; }
            [JsonProperty("type")]
            public string buildingType { get; set; }
            public string buildingTypeCode { get; set; }
            public string buildingTypeDescription { get; set; }            

            [JsonProperty("floors")]
            public List<floorInvolved> floorsInvolved { get; set; }            
        }

        public class floorInvolved
        {
            public string InvolvedId { get; set; }
            public List<FRole> roles { get; set; }
        }

        public class FRole
        {
            public string code { get; set; }
            public string description { get; set; }
        }                     


  
 Sample Data:


{
"result": "200 OK",

"propertyData": {

"building": [


{
"itemId": "9A85B1CCBD65C1F2",
"type": "V",
"buildingTypeCode": "02",
"buildingTypeDescription": "mixed space",

"floors": [

{
"InvolvedId": "04",

"roles": [

{
"code": "OFF",
"description": "Office space"
},

{
"code": "APT",
"description": "Apartment"
},

{
"code": "STG",
"description": "Storage"
}
]
},
{
"InvolvedId": "05",

"roles": [

{
"code": "OFF",
"description": "Office space"
},


]
}
],

}
]
}
}
  
 I'm trying to get the building bubbled up with the details like this:
ID                Description  Floor  Role
9A85B1CCBD65C1F2  mixed space    04   Office space, Apartment, Storage
9A85B1CCBD65C1F2  mixed space    05   Office space

  
 I load the json data like so
var resulting = JsonConvert.DeserializeObject<Exampleobject>(rawjson);
  

Комментарии:

1. SelectMany в синтаксисе метода расширения или from x in xs from y in x.ys ... в синтаксисе запроса.

2. Я играл с SelectMany, и я все еще не могу приблизиться к ответу о том, как правильно использовать LINQ в этой ситуации

Ответ №1:

Использование синтаксиса запроса:

 var result =
    from building in resulting.propertyData.building
    from floor in building.floorsInvolved
    select $"{building.itemId} {building.buildingTypeDescription} "  
        $"{floor.InvolvedId} "  
        $"{string.Join(", ", floor.roles.Select(role => role.description))}";
  

Или альтернативно (и, возможно, немного более читабельно):

 var result =
    from building in resulting.propertyData.building
    from floor in building.floorsInvolved
    let roles = floor.roles.Select(role => role.description)
    select $"{building.itemId} {building.buildingTypeDescription} "  
        $"{floor.InvolvedId} {string.Join(", ", roles)}";
  

Использование синтаксиса метода расширения:

  var result = resulting.propertyData.building
    .SelectMany(building => building.floorsInvolved
        .Select(floor => $"{building.itemId} {building.buildingTypeDescription} "  
            $"{floor.InvolvedId} "  
            $"{string.Join(", ", floor.roles.Select(role => role.description))}"));
  

Комментарии:

1. Красивый — работает как шарм, и я, наконец, получил некоторое представление о том, как продолжить использовать LINQ для этих данных. Я должен тебе много пива!