• 开源一个小类库, 用于对象间灵活的拷贝属性,还有IDataReader到实体类的转换


    功能一:

    背景:

      编程中经常有这个需求,要在两个非常类似的实体类中,拷贝同名属性的值,(例如在WCF实体和EF实体中的拷贝...)

      以往一般有两个方案

        1.硬编码:执行效率很高,不过要写很多重复的代码,

        2.反射: 灵活,不过效率非常低

    这里提供一个灵活性不比反射差的解决方案  https://github.com/xwj90/Clover.Copyer

    使用代码非常简单,如下所示, 只有一句话

     //范例一  在两个对象直接拷贝属性
    ClassA target = new ClassA();
    ClassB source = new ClassB() { A = "AA", B = 2, C = DateTime.Now };

    //复制代码
    CopyHelper<ClassB, ClassA>.Copy(source, target);//这一句是调用方法

    Console.WriteLine(target.A);
    Console.WriteLine(target.B);
    Console.WriteLine(target.C);



    两个类型的定义如下:

        public sealed class ClassA
    {

    public string A { get; set; }
    public int B { get; set; }
    public string Title { get; set; }
    public int Id { get; set; }
    public DateTime C { get; set; }

    }
    public sealed class ClassB
    {
    public string A { get; set; }
    public int B { get; set; }
    public DateTime C { get; set; }
    }

    备注:支持所有类型的公开实例属性

      不支持索引器

    功能二:

      从数据库提供的IDataReader中读取出对应的值,并转换成相应类型赋值给实体类,

      省掉了中间的Dataset的过程,也节省了很多类型转换和硬编码的工作

      先看看代码:

                //范例二  从IDataReader中读取属性
    string connString = "Data Source=.;Initial Catalog=Northwind;Persist Security Info=True;";
    for (int i = 0; i < 1; i++)
    {

    using (SqlConnection conn = new SqlConnection(connString))
    {
    SqlCommand command = new SqlCommand();
    command.Connection = conn;
    command.CommandText = "select top 1000 * from cLog";
    conn.Open();
    IDataReader reader = command.ExecuteReader();
    var list = CopyHelper<TestClassA>.Copy(reader);//这一句是调用方法
    foreach (var item in list)
    {
    Console.Write(item.LogId + "---");
    Console.Write(item.LogTime + "---");
    Console.Write(item.AppName + "---");
    Console.Write(item.Server + "---");
    Console.Write(item.IPAddress + " ");
    Console.WriteLine();
    }
    }
    }

    备注:支持所有基本类型,每次返回的列的顺序要一样,  不要一会儿select a,b from table  然后一会儿 select b,a from table (自动探测要消耗很多性能,以后再实现)

    实现原理:
    第一次的时候使用反射分析类型, 然后使用ILEmit 生成动态方法

    将动态方法缓存下来,第二次的时候就可以直接使用该方法了

    性能:

    基本上在属性比较多的类型中效率比例大约为  

    硬编码:动态方法:反射

    1:5-10:100-1000  (实际测试的时候类中大约有 1-30个属性)

     还请各位提点意见

  • 相关阅读:
    CCCC L3-015. 球队“食物链”(dfs+剪枝)
    【USACO2.1】解题报告
    【USACO2.1】解题报告
    序列【模拟】
    序列【模拟】
    【JZOJ5184】Gift【DP】【01背包】
    【JZOJ5184】Gift【DP】【01背包】
    【JZOJ5177】TRAVEL【并查集】
    【JZOJ5177】TRAVEL【并查集】
    【JZOJ5178】So many prefix?【KMP】【DP】
  • 原文地址:https://www.cnblogs.com/PurpleTide/p/2388956.html
Copyright © 2020-2023  润新知