2016-12-01 54 views
1

我有一個複雜的JSON結構(至少對我來說),看起來像獲取COMPLE JSON結構與LINQ一筆

{ 
"Assets": [{ 
     "Name": "asset1", 
     "Code": "SS-15", 
     "Items": [{ 
       "Name": "Item1", 
       "KGs": 255, 
       "Cartons": 1222, 
       "Containers": 3 
      }, { 
       "Name": "Item2", 
       "KGs": 150, 
       "Cartons": 2322, 
       "Containers": 5 
      } 
     ] 
    }, { 
     "Name": "asset2", 
     "Code": "SA-23", 
     "Items": [{ 
       "Name": "Item1", 
       "KGs": 88, 
       "Cartons": 40, 
       "Containers": 1 
      }, { 
       "Name": "Item2", 
       "KGs": 960, 
       "Cartons": 710, 
       "Containers": 31 
      } 
     ] 
    } 
]} 

我需要在全球範圍內總結有多少幼兒園,上貨櫃是對每種類型項目,是這樣的:

[{ 
    "unit": "KGs", 
    "Item1": 343, 
    "Item2": 1110 

}, { 
    "unit": "Cartons", 
    "Item1": 1262, 
    "Item2": 3032 
}, { 
    "unit": "Containers", 
    "Item1": 4, 
    "Item2": 36 
}] 

我一直在使用LINQ,到目前爲止,我有這樣的:

object.SelectMany(x => x.Items.GroupBy(k => k.Name, m => m.KGs)).GroupBy(g => g.Key); 

看起來我在尋找什麼,但沒有給我需要的信息。

注:我反序列化json到我的項目中的一個類。

+0

如果它不是你需要的信息,它給你什麼?此外,因爲您之後再次使用「GroupBy」,我不會在您的「SelectMany」中使用「GroupBy」。 – RandomStranger

+0

它給了我一個分組清單 Yatiac

+0

@Yatiac你會一直有Item1和Item2或者其他人嗎? – CodingYoshi

回答

1

我不知道你是否會嘲笑這件事或是因爲它離你所期望的距離太遠,但是我在這段代碼中看到的主要問題是你試圖在(Item1,Item2)到屬性(「Item1」:4,「Item2」:36),這迫使我考慮使用ExpandoObject類動態創建對象:

(您必須安裝並導入MoreLinq爲了使用DistinctBy)

var unitsNames = o["Assets"].SelectMany(a => a["Items"]).DistinctBy(i=>i["Name"]).Select(i=>i["Name"].ToString()); 
var allUnits=o["Assets"].SelectMany(a=>a["Items"]); 

var kgs=GetExpandoObject(unitsNames, allUnits,"KGs"); 
var cartons = GetExpandoObject(unitsNames, allUnits, "Cartons"); 
var containers = GetExpandoObject(unitsNames, allUnits, "Containers"); 

List<ExpandoObject> res = new List<ExpandoObject>() 
{ 
    kgs as ExpandoObject,cartons as ExpandoObject,containers as ExpandoObject 
}; 


string jsonString = JsonConvert.SerializeObject(res); 

...

private static IDictionary<string, object> GetExpandoObject(IEnumerable<string> unitsNames, IEnumerable<JToken> allUnits, string concept) 
    { 
     var eo = new ExpandoObject() as IDictionary<string, Object>; 
     eo.Add("unit", concept); 

     foreach (var u in unitsNames) 
     { 
      var sum = allUnits.Where(un => un["Name"].ToString() == u).Sum(_ => (int)_[concept]); 
      eo.Add(u, sum); 
     } 

     return eo; 
    } 

這是結果:

[ 
{"unit":"KGs","Item1":343,"Item2":1110}, 
{"unit":"Cartons","Item1":1262,"Item2":3032}, 
{"unit":"Containers","Item1":4,"Item2":36} 
] 

我並不是說這是不可能用單一的LINQ查詢做的,但我沒有看到它說清楚,也許有人聰明和/或用更多的時間可能實現它