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

c#从另一个键值实体设置实体属性,c#,entity-framework,reflection,C#,Entity Framework,Reflection,我有一个包含键和值的实体。我的钥匙是enum。值是此实体上的字符串(但其数据类型可能不同于字符串) 枚举示例: public enum CallKey { CallDate = 1, CallTime = 2, FromPhoneNumber = 3, ToPhoneNumber = 4, Duration = 5, FromOperatorCode = 6, ToOperatorCode = 7 } 我的关键价值实体是: public

我有一个包含键和值的实体。我的钥匙是enum。值是此实体上的字符串(但其数据类型可能不同于字符串)

枚举示例:

 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实体?反射、逐个属性还是其他更好的方法?

好的,我想我找到了一些解决这个问题的方法。我做了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;
}
}
公共类调用测试{
公共void TestCode(){
var items=新列表
{
新的CallKeyValue{CallKey=CallKey.CallDate,Value1=“11.04.2017”},
新的CallKeyValue{CallKey=CallKey.CallTime,Value1=“15:43”},
新的CallKeyValue{CallKey=CallKey.FromPhoneNumber,Value1=“5311234567”},
新的CallKeyValue{CallKey=CallKey.ToPhoneNumber,Value1=“5311234587”},
新的CallKeyValue{CallKey=CallKey.Duration,Value1=“13*min”},
新的CallKeyValue{CallKey=CallKey.FromOperatorCode,Value1=“TR”,Value2=“001”},
新的CallKeyValue{CallKey=CallKey.ToOperatorCode,Value1=“TR”,Value2=“002”},
};
var st=新秒表();
//测试1:ElapsedMills:50,ElapsedTicks:122023
st.Start();
IDictionary expando=新的ExpandoObject();
foreach(项目中的var项目){
expando.Add(item.CallKey.ToString(),null);
expando[item.CallKey.ToString()]=new{Value1=item.Value1,Value2=item.Value2};
}
var cd=newcalldetail{
CallDate=DateTime.Parse(expando[CallKey.CallDate.ToString()].Value1+“”+expando[CallKey.CallTime.ToString()].Value1),
FromPhoneNumber=expando[CallKey.FromPhoneNumber.ToString()]值1,
ToPhoneNumber=expando[CallKey.ToPhoneNumber.ToString()]。值1,
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()]。值1,
FromOperatorId=expando[CallKey.FromOperatorCode.ToString()]值2,
ToOperatorCountry=expando[CallKey.ToOperatorCode.ToString()]。值1,
ToOperatorId=expando[CallKey.ToOperatorCode.ToString()]值2
};
st.Stop();
控制台写入线(st.elapsedmillyses);
控制台写入线(圣埃拉普塞迪克);
圣重置();
//测试2:ElapsedMills:0,ElapsedTicks:328
st.Start();
var cd3=项目。选择(s=>{
IDictionary expando2=新的ExpandoObject();
expando2.Add(s.CallKey.ToString(),null);
expando2[s.CallKey.ToString()]=new{Value1=s.Value1,Value2=s.Value2};
var item=newcalldetail{
CallDate=DateTime.Parse(expando2[CallKey.CallDate.ToString()].Value1+“”+expando2[CallKey.CallTime.ToString()].Value1),
FromPhoneNumber=expando2[CallKey.FromPhoneNumber.ToString()]值1,
ToPhoneNumber=expando2[CallKey.ToPhoneNumber.ToString()]值1,
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()]。值1,
FromOperatorId=expando2[CallKey.FromOperatorCode.ToString()]值2,
ToOperatorCountry=expando2[CallKey.ToOperatorCode.ToString()]值1,
ToOperatorId=expando2[CallKey.ToOperatorCode.ToString()]值2
};
退货项目;
});
st.Stop();
控制台写入线(st.elapsedmillyses);
控制台写入线(圣埃拉普塞迪克);
圣重置();
//测试3:ElapsedMills:0,ElapsedTicks:1390
st.Start();
var cd2=新的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();
控制台写入线(st.elapsedmillyses);
控制台写入线(圣埃拉普塞迪克);
}
私有持续单位?GetEnumKeyOfUnit(字符串单位){
开关(单位){
案例“min”:
返回持续时间单位:分钟;
案例“小时”:
返回持续时间单位:小时;
}
返回null;
}
}

在测试之前,我尝试使用反射。反射性能比3次测试差得多。它是ElapsedMills大约是100秒,而且elapsedticks非常高。我可能会使用第二次测试,直到找到更好的方法

如果你能在这里提供一些背景资料,可能会有帮助。你想解决什么问题?我有一个性能问题。这只是一个例子,但我有更多的数据。反思是一个很好的解决方案,但我认为(可能是我的方式错了,我不确定)它是缓慢的。反思本身可能不起作用(除非你做的事情比我多)