c#从另一个键值实体设置实体属性

时间:2017-04-11 12:54:08

标签: c# entity-framework reflection

我有一个包含键和值的实体。我的关键是枚举。值是此实体的字符串(但它们的数据类型可能与字符串不同)。

枚举示例:

 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
}

设置Call​​Detail实体的方法是什么?反思,财产或其他更好的方式?

1 个答案:

答案 0 :(得分:0)

好的,我想我找到了一些关于这个问题的解决方案。我做了3次测试,我在这里添加了一个简单的样本。我认为第二对我来说是最好的,但我决定进行加载测试。

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次测试要差。它的流逝时间大约是100,也就是已经过了很长的时间。我可以使用第二次测试,直到找到更好的方式。