2017-04-11 6 views
0

私はキーと値を含むエンティティを持っています。私の鍵はenumです。値はこのエンティティの文字列です(ただし、データ型は文字列と異なる場合があります)。c#別のキー値エンティティのエンティティプロパティを設定します

列挙例:

public enum CallKey { 
    CallDate = 1, 
    CallTime = 2, 
    FromPhoneNumber = 3, 
    ToPhoneNumber = 4, 
    Duration = 5, 
    FromOperatorCode = 6, 
    ToOperatorCode = 7 
} 

私のキーと値の実体がある:

public class CallKeyValue { 
    public CallKey CallKey { get; set; } 
    public string Value1 { get; set; } 
    public string Value2 { get; set; } 
} 

私の例のキー、値のデータは次のとおりです。

CallKey |Value1  |Value2 
1  |11.04.2017 | 
2  |15:43  | 
3  |5311234567 | 
4  |5311234587 | 
5  |13*min  | 
6  |TR   |001 
7  |TR   |002 

、私は最終的に作成したいですエンティティをキー値エンティティから取得します。

私の最後のエンティティ:

public class CallDetail{ 
    public DateTime CallDate { get; set; } //=15.04.2017 15:43 
    public string FromPhoneNumber { get; set; } //=5311234567 
    public string ToPhoneNumber { get; set; } //=5311234587 
    public int Duration { get; set; } //=13 
    public DurationUnit DurationUnit { get; set; } //=1 (this is enum 1:min, 2:hour etc...) 
    public string FromOperatorCountry { get; set; } //=TR 
    public string FromOperatorId { get; set; } //=001 
    public string ToOperatorCountry { get; set; } //=TR 
    public string ToOperatorId { get; set; } //=002 
} 

がCallDetailエンティティを設定する方法はありますか?反射、プロパティまたは別のより良い方法でプロパティ?

+0

ここで背景を説明できるのは有益でしょう。ここで解決しようとしている問題は何ですか? – jcb

+0

私はパフォーマンス上の問題があります。これは単なる例ですが、私はより多くのデータを持っています。反射は良い解決策ですが、私は(私の方法は間違っているかもしれませんが、わかりません)それは遅いと思います。 –

+0

あなたの質問からはっきりと分かるものを除き、反射だけではうまくいきません。例えば、 'CallDetail'の知識が必要で、' CallKey.Duration'型の文字列 "13 * min"が 'CallDetail.Duration'と' CallDetail.DurationUnit'に分割される必要があることがわかります。前者は同じ名前のプロパティを検索することで見つけることができますが、後者はどのような方法でも明白ではありません(一般的な反映ソリューションが利用できるメタ情報がない限り)。 – jcb

答えて

0

私はこの問題についていくつか解決策を見つけたと思います。私は3回のテストを行い、ここでは簡単なサンプルを追加します。私は2番目が最善だと思っていますが、私はローディングテストをすることに決めました。

public class CallTest { 
public void TestCode() { 
    var items = new List<CallKeyValue> 
    { 
     new CallKeyValue {CallKey = CallKey.CallDate, Value1 = "11.04.2017"}, 
     new CallKeyValue {CallKey = CallKey.CallTime, Value1 = "15:43"}, 
     new CallKeyValue {CallKey = CallKey.FromPhoneNumber, Value1 = "5311234567"}, 
     new CallKeyValue {CallKey = CallKey.ToPhoneNumber, Value1 = "5311234587 "}, 
     new CallKeyValue {CallKey = CallKey.Duration, Value1 = "13*min"}, 
     new CallKeyValue {CallKey = CallKey.FromOperatorCode, Value1 = "TR",Value2 = "001"}, 
     new CallKeyValue {CallKey = CallKey.ToOperatorCode, Value1 = "TR",Value2 = "002"}, 
    }; 
    var st = new Stopwatch(); 

    //Test 1: ElapsedMilliseconds: 50, ElapsedTicks: 122023 
    st.Start(); 
    IDictionary<string,dynamic> expando = new ExpandoObject(); 
    foreach(var item in items) { 
     expando.Add(item.CallKey.ToString(),null); 
     expando[item.CallKey.ToString()] = new { Value1 = item.Value1,Value2 = item.Value2 }; 
    } 

    var cd = new CallDetail { 
     CallDate = DateTime.Parse(expando[CallKey.CallDate.ToString()].Value1 + " " + expando[CallKey.CallTime.ToString()].Value1), 
     FromPhoneNumber = expando[CallKey.FromPhoneNumber.ToString()].Value1, 
     ToPhoneNumber = expando[CallKey.ToPhoneNumber.ToString()].Value1, 
     Duration = Convert.ToInt32(expando[CallKey.Duration.ToString()].Value1.ToString().Split('*')[0]), 
     DurationUnit = GetEnumKeyOfUnit(expando[CallKey.Duration.ToString()].Value1.ToString().Split('*')[1]), 
     FromOperatorCountry = expando[CallKey.FromOperatorCode.ToString()].Value1, 
     FromOperatorId = expando[CallKey.FromOperatorCode.ToString()].Value2, 
     ToOperatorCountry = expando[CallKey.ToOperatorCode.ToString()].Value1, 
     ToOperatorId = expando[CallKey.ToOperatorCode.ToString()].Value2 
    }; 
    st.Stop(); 
    Console.WriteLine(st.ElapsedMilliseconds); 
    Console.WriteLine(st.ElapsedTicks); 
    st.Reset(); 

    //Test 2: ElapsedMilliseconds: 0, ElapsedTicks: 328 
    st.Start(); 
    var cd3 = items.Select(s => { 
     IDictionary<string,dynamic> expando2 = new ExpandoObject(); 
     expando2.Add(s.CallKey.ToString(),null); 
     expando2[s.CallKey.ToString()] = new { Value1 = s.Value1,Value2 = s.Value2 }; 

     var item = new CallDetail { 
      CallDate = DateTime.Parse(expando2[CallKey.CallDate.ToString()].Value1 + " " + expando2[CallKey.CallTime.ToString()].Value1), 
      FromPhoneNumber = expando2[CallKey.FromPhoneNumber.ToString()].Value1, 
      ToPhoneNumber = expando2[CallKey.ToPhoneNumber.ToString()].Value1, 
      Duration = Convert.ToInt32(expando2[CallKey.Duration.ToString()].Value1.ToString().Split('*')[0]), 
      DurationUnit = GetEnumKeyOfUnit(expando2[CallKey.Duration.ToString()].Value1.ToString().Split('*')[1]), 
      FromOperatorCountry = expando2[CallKey.FromOperatorCode.ToString()].Value1, 
      FromOperatorId = expando2[CallKey.FromOperatorCode.ToString()].Value2, 
      ToOperatorCountry = expando2[CallKey.ToOperatorCode.ToString()].Value1, 
      ToOperatorId = expando2[CallKey.ToOperatorCode.ToString()].Value2 
     }; 
     return item; 
    }); 


    st.Stop(); 
    Console.WriteLine(st.ElapsedMilliseconds); 
    Console.WriteLine(st.ElapsedTicks); 
    st.Reset(); 

    //Test 3: ElapsedMilliseconds: 0, ElapsedTicks: 1390 
    st.Start(); 
    var cd2 = new CallDetail { 
     CallDate = DateTime.Parse(items.FirstOrDefault(f => f.CallKey == CallKey.CallDate)?.Value1 + " " + items.FirstOrDefault(f => f.CallKey == CallKey.CallTime)?.Value1), 
     FromPhoneNumber = items.FirstOrDefault(f => f.CallKey == CallKey.FromPhoneNumber)?.Value1, 
     ToPhoneNumber = items.FirstOrDefault(f => f.CallKey == CallKey.ToPhoneNumber)?.Value1, 
     Duration = Convert.ToInt32(items.FirstOrDefault(f => f.CallKey == CallKey.Duration)?.Value1.Split('*')[0]), 
     DurationUnit = GetEnumKeyOfUnit(items.FirstOrDefault(f => f.CallKey == CallKey.Duration)?.Value1.Split('*')[1]), 
     FromOperatorCountry = items.FirstOrDefault(f => f.CallKey == CallKey.FromOperatorCode)?.Value1, 
     FromOperatorId = items.FirstOrDefault(f => f.CallKey == CallKey.FromOperatorCode)?.Value2, 
     ToOperatorCountry = items.FirstOrDefault(f => f.CallKey == CallKey.ToOperatorCode)?.Value1, 
     ToOperatorId = items.FirstOrDefault(f => f.CallKey == CallKey.ToOperatorCode)?.Value2 
    }; 

    st.Stop(); 
    Console.WriteLine(st.ElapsedMilliseconds); 
    Console.WriteLine(st.ElapsedTicks); 

} 

private DurationUnit? GetEnumKeyOfUnit(string unit) { 
    switch(unit) { 
     case "min": 
      return DurationUnit.Minute; 
     case "hour": 
      return DurationUnit.Hour; 
    } 
    return null; 
} 
} 

このテストの前に、私は反射を使用しようとしました。反射性能は3回の試験よりも非常に悪い。それはelapsedmillisecondsが約100であり、elapsedticksも非常に高いです。私はより良い方法を見つけるまで、2番目のテストを使用することがあります。

関連する問題