0

ローカリゼーションデータベースには、次のオブジェクトがあります。

public class Text
{
  public string Key { get; set; }
  public string LanguageId { get; set; }
  public string Value { get; set; }
}

これらのレコードを、次のような値を持つプロパティとしてLanguageIdsを持つ構造にフラット化するには、Linqステートメントが必要です。

public class ...
{
  public string Key { get; set; }
  public string En { get; set; }
  public string Ge { get; set; }
  public string Fr { get; set; }
  ...
}

もちろん、これはいくつかの手の込んだ「foreach」によって達成できますが、一度にトリックを実行する洗練されたLinqステートメントが必要です。そこにリンクの達人はいますか?

4

4 に答える 4

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」オブジェクトのプロパティとして存在する必要があることに注意してください。存在しない場合、GetProperty()がnullを返すため、NullReferenceExceptionが発生します。

于 2012-11-14T10:52:28.810 に答える
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 
                     });

もちろん、どの言語を使用しているかを知る必要があります...

于 2012-09-03T08:28:59.367 に答える
0

意味が理解できたら、最初のオブジェクトから2番目のオブジェクトを作成し、これをLinqステートメントに統合できます。たとえば次のようになります。

  var result = TextObjectList.Select(x => new LanguageObject(x))

また、LanguageObjectコンストラクターで、LanguageIdまでの値を設定します。

于 2012-09-03T08:20:49.110 に答える
0

あなたは次のようなことをすることができます:

typeof(MyClass).GetProperties().AsEnumerable().Select(x => new () {Key = x.Name, En = "English", Ge = "German (shouldn't it be De?)" ... }
于 2012-09-03T08:21:09.613 に答える