2015-05-09 5 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

какой контекст.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

Я не думаю, что вы можете сделать это с Purly 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); 

Для этого входа: [{ "А": 1, "В": 2, "С": 3}, { "А": 1, «B»: 1, «D»: 1}]

Он дает следующий результат: {«A»: [1,1], «B»: [2,1], «C»: [3], «D»: [1]}

Конечно, если у вас сильно типизированные классы, вам не нужно использовать отражение. Вы также можете передавать типы классов для агрегирования и записи сопоставления самостоятельно.

+0

Это тоже сработало - спасибо Фабиану. dbc получил шоколад для элегантного запроса linq – Xcheque

Смежные вопросы