我有一个包含大量属性的对象模型。从数据库中提取这些属性的值,以提供IEnumerable
列表或数组,如下所示:
var obj = context.Model.Where(x => idList.Contains(x.Id)).ToList();
这给出了这个结构中的Json输出blob:
[{ 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 :(得分: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。
答案 1 :(得分: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]}
当然,如果您有强类型类,则不需要使用反射。您还可以传递类类型以自行聚合和编写映射。