在我们的本地化数据库中,我们有以下对象:
public class Text
{
public string Key { get; set; }
public string LanguageId { get; set; }
public string Value { get; set; }
}
我需要一个Linq语句来将这些记录展平为一个结构,该结构将LanguageId作为属性,其值如下:
public class ...
{
public string Key { get; set; }
public string En { get; set; }
public string Ge { get; set; }
public string Fr { get; set; }
...
}
当然,这可以通过一些精心设计的“为每个人”来实现,但必须有一个明确的Linq语句一次完成这个技巧。 有没有Link Guru?
答案 0 :(得分:4)
我偶然发现了这个问题,只是想为这个问题添加我的解决方案。我冒昧地围绕表达式产生了一个小的可运行的例子:
public class LocalizationManager
{
public IDictionary<string, Localization> LostInTranslation()
{
var input = new[]
{
new Text {Key = "ORDINAL_1", LanguageId = "En", Value = "first"},
new Text {Key = "ORDINAL_1", LanguageId = "Fr", Value = "premier"},
new Text {Key = "ORDINAL_1", LanguageId = "De", Value = "erste"},
new Text {Key = "ORDINAL_2", LanguageId = "En", Value = "second"},
new Text {Key = "ORDINAL_2", LanguageId = "Fr", Value = "deuxième"},
new Text {Key = "ORDINAL_2", LanguageId = "De", Value = "zweite"},
new Text {Key = "ORDINAL_3", LanguageId = "En", Value = "third"},
new Text {Key = "ORDINAL_3", LanguageId = "Fr", Value = "troisième"},
new Text {Key = "ORDINAL_3", LanguageId = "De", Value = "dritte"},
};
var output =
input.GroupBy(text => text.Key).Select(
group =>
group.Aggregate(new Localization { Key = group.Key },
(translation, text) =>
{
translation.GetType().GetProperty(text.LanguageId).SetValue(translation, text.Value, null);
return translation;
}));
return output.ToDictionary(key => key.Key);
}
}
public class Text
{
public string Key { get; set; }
public string LanguageId { get; set; }
public string Value { get; set; }
}
public class Localization
{
public string Key { get; set; }
public string En { get; set; }
public string De { get; set; }
public string Fr { get; set; }
}
虽然这似乎是对Aggregate()的轻微歪曲,但我认为它的精神是真实的。请注意,所有语言都必须作为“Localization”对象的属性存在,否则您将获得NullReferenceException,因为GetProperty()返回null。
答案 1 :(得分:3)
尝试以下方法:
var flattenTexts = texts
.GroupBy(x => x.Key)
.Select(x => new { Key = x.Key,
De = x.First(y => y.LanguageId == "De").Value,
En = x.First(y => y.LanguageId == "En").Value
});
您当然需要知道您拥有哪种语言......
答案 2 :(得分:0)
如果我明白你的意思,你可以从第一个中创建第二个对象并将其集成到你的Linq语句中,例如:
var result = TextObjectList.Select(x => new LanguageObject(x))
在LanguageObject Constructor中将值设置为LanguageId。
答案 3 :(得分:0)
您可以执行以下操作:
typeof(MyClass).GetProperties().AsEnumerable().Select(x => new () {Key = x.Name, En = "English", Ge = "German (shouldn't it be De?)" ... }