2015-05-09 553 views
1

我有一个具有大量属性的对象模型。这些属性的值是从数据库中提取,得到IEnumerable列表或数组像这样:将IEnumerable对象列表转换为对象数组列表C#

var obj = context.Model.Where(x => idList.Contains(x.Id)).ToList(); 

这给出了在该结构中一个JSON输出斑点:

[{ Prop1: 57, Prop2: 2, Prop3: 25 ... }, 
{ Prop1: 23, Prop2: 4, Prop3: 20 ....}, 
{ Prop1: 15, Prop2: 6, Prop3: 32 ....}, 
... ] 

是否有一种方法可以设置LINQ查询以这种形式来提取数据:

{ Prop1: [57,23,15, ...], 
    Prop2: [2,4,6, ....], 
    Prop3: [25,20,32, ...], 
    ... } 

换句话说欲对象阵列的集合不是对象

0的数组
+0

什么context.Model.Where(x => idList.Contains(x.Id))。ToArray();给你? –

+0

是的,我们需要关于模型类 –

+0

的详细信息,Fabian和dbc都有这个要点。更好的是,他们的解决方案都处理一般对象结构和可空类型。 – Xcheque

回答

2

如果您正在使用Json.NET,您可以用LINQ to JSON重组的JSON在一个完全通用的方式,而不需要编写自己的反射代码:

 var jArray = JArray.FromObject(obj); // obj must serialized to an array; throw an exception otherwise. 
     var jObj = new JObject(jArray   // Allocate new outer JSON object 
      .Cast<JObject>()     // All array element must be json objects 
      .SelectMany(o => o.Properties()) 
      .GroupBy(p => p.Name, p => p.Value) // Group all array element properties by name 
      .Select(g => new JProperty(g.Key, g))); // Add an array-valued property to the new outer object. 
     var json = jObj.ToString(); 
     Debug.WriteLine(json); 

鉴于以下输入obj

 var obj = new List<object> 
     { 
      new { Prop1 = 57, Prop2 = 2, Prop3 = 25 }, 
      new { Prop1 = 23, Prop2 = 4, Prop3 = 20 }, 
      new { Prop1 = 15, Prop2 = 6, Prop3 = 32 }, 
     }; 

以下JSON产生:

{"Prop1":[57,23,15],"Prop2":[2,4,6],"Prop3":[25,20,32]} 

另外,如果您obj是强类型,您可以手动创建用于输出的中间anonymous type,就像这样:

 var newObj = new { Prop1 = obj.Select(i => i.Prop1), Prop2 = obj.Select(i => i.Prop2), Prop3 = obj.Select(i => i.Prop3) }; 

然后,给出下面的输入obj

 var obj = new[] 
     { 
      new [] { 57,2,25 }, 
      new [] { 23,4,20 }, 
      new [] { 15,6,32 }, 
     } 
     .Select(a => new { Prop1 = a[0], Prop2 = a[1], Prop3 = a[2] }); 

的生成相同的JSON。

+0

不错的代码 - 谢谢 – Xcheque

1

我不认为你可以用纯粹的Linq做到这一点,如果你想通用。你需要至少使用一些反射来遍历你的属性。

下面的代码应该做哟想要的:

 var list = new List<object> {new { A = 1, B = 2, C = 3}, new {A = 1, B = 1, D = 1}}; 

     var result = new ExpandoObject(); 

     var list1 = list.Aggregate<object, ExpandoObject>(result, (res, a) => 
     { 
      foreach (var prop in a.GetType().GetProperties()) 
      { 
       object val = prop.GetValue(a); 

       var x = res as IDictionary<string, Object>; 
       object o; 
       if (!x.TryGetValue(prop.Name, out o)) 
       { 
        o = new List<object>(); 
        x.Add(prop.Name, o); 
       } 

       ((List<object>)o).Add(val); 
      } 

      return res; 
     }); 

      var inputJson = Newtonsoft.Json.JsonConvert.SerializeObject(list); 

     var outputJson = Newtonsoft.Json.JsonConvert.SerializeObject(list1); 

对于此输入:[{ “A”:1, “B”:2, “C”:3},{ “A”: 1,“B”:1,“D”:1}]

它给出以下输出:{“A”:[1,1],“B”:[2,1],“C”: [3],“D”:[1]}

当然,如果你有强类型的类,你不需要使用反射。您也可以传递类类型来自行聚合和写入映射。

+0

这也工作 - 谢谢Fabian。 dbc为优雅的linq查询得到了巧克力 – Xcheque