使用属性的值作为匿名对象中的属性名称

时间:2019-02-27 07:05:43

标签: c# linq

是否可以在.Select(...)语句中将属性的值用作匿名对象的值?

我从服务器返回了一个简单的项目清单,我将这些清单按属性分组。 从数据库返回的对象看起来像:

public class Locale
{
    public int LanguageId { get; set; }
    public string Key { get; set; }
    public string Value { get; set; }
    public string ParentKey { get; set; }
}

一个简单的EF查询从数据库中带回所有项目:

var locales = await _context.Locales.ToListAsync();

然后我将其分组:

var result = locales.GroupBy(x => x.ParentKey).Where(x => null != x.Key);

然后,我想使用密钥(例如“ _title”)作为匿名对象中的属性名称。原因是,我需要将数据传递给第三方Angular组件,他们期望return属性是“键”的值,而属性的值是Value。

我到目前为止的尝试,但这不起作用:

var output = result.SelectMany(x => new {
    lang = x.Key,
    data = x.SelectMany(p => new {
        p.Key = p.Value
    })
});

原因是匿名方法需要定义的属性名称。 我本来希望没有复杂的反射/ JObject路由,但这似乎是唯一的方法。

1 个答案:

答案 0 :(得分:2)

您可以将每个分组投影到字典中。然后将其序列化并获得所需的输出:

var output = locales.Where(x => x.ParentKey != null)
                    .GroupBy(x => x.ParentKey)                                
                    .Select(x => new {
                        lang = x.Key,
                        data = x.ToDictionary(k => k.Key, v => v.Value)
                    });

var json = Newtonsoft.Json.JsonConvert.SerializeObject(output);

例如数据:

var locales = new List<Locale> {
    new Locale { LanguageId = 1, Key = "a", Value = "1", ParentKey = "1" },
    new Locale { LanguageId = 2, Key = "b", Value = "2", ParentKey = "2" },
    new Locale { LanguageId = 3, Key = "c", Value = "3", ParentKey = "2" },
};

产量:

[{"lang":"1","data":{"a":"1"}},
 {"lang":"2","data":{"b":"2","c":"3"}}]