zoukankan      html  css  js  c++  java
  • 反射和特性 自定义转换datatable为强类型集合

     转换类:

    View Code
       public static class ListGenerater
        {
            //加入DataTable扩展方法
            public static List<T> ConvertToList<T>(this DataTable dt)
            {
                Type type = typeof(T);
                var fieldBinding = BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance;
                    //得到数据库字段名和类名的映射关系
                var  mappings = type.GetProperties()
                                  .Where((item) =>
                                  {
                                      var attrs = item.GetCustomAttributes(typeof(DBColumnAttribute), false);
                                      return attrs.Length > 0;
                                  })
                                   .Select((item) =>
                                   {
                                       var attr = item.GetCustomAttributes(typeof(DBColumnAttribute), false)[0] as DBColumnAttribute;
                                       var dbName=(string.IsNullOrEmpty(attr.DbName) ? item.Name : attr.DbName);
                                       var storage = string.IsNullOrEmpty(attr.Storage) ? null : type.GetField(attr.Storage, fieldBinding);
                                       return new
                                       {
                                           Type = item.PropertyType,
                                           DbName = dbName,
                                           Property = item,
                                           StorageField=storage
                                       };
                                   });
    
                //动态生成类,根据映射关系得到datatable里的数据,再赋值到类中
                List<T> list = new List<T>();
                foreach (DataRow row in dt.Rows)
                {
                    T temp = Activator.CreateInstance<T>();
                    foreach (var mapping in mappings)
                    {
                        if (mapping.StorageField==null)
                        {
                            mapping.Property.SetValue(temp, row[mapping.DbName], null);
                        }
                        else
                        {
                            mapping.StorageField.SetValue(temp, row[mapping.DbName]);
                        }
                    }
                    list.Add(temp);
                }
                return list;
            }
    
        }
    
        [AttributeUsage(AttributeTargets.Property, AllowMultiple = false)]
        public class DBColumnAttribute : Attribute
        {
            /// <summary>
            /// 对应数据集中的字段名
            /// </summary>
            public string DbName { get; set; }
            /// <summary>
            /// 存储的字段,如果设置,会绕过属性存取器,直接对字段赋值
            /// </summary>
            public string Storage { get; set; }
        }

    测试代码:

    View Code
        class Program
        {
            static void Main(string[] args)
            {
                string constr = "Data Source=.;Initial Catalog=ShiShangDBx;Integrated Security=True";
                string querystr = "select top(5) * from [User]";
                SqlDataAdapter ada = new SqlDataAdapter(querystr, constr);
                DataTable dt = new DataTable();
                ada.Fill(dt);
    
                var p = new Program();
                p.TestDynamic(dt);
                p.TestStatic(dt);
                
            }
    
            public void TestDynamic(DataTable dt)
            {
                var watch = Stopwatch.StartNew();
                watch.Start();
    
                for (int i = 0; i < 10000; i++)
                {
                    var userlist = dt.ConvertToList<UserInfo>();
                }
                watch.Stop();
                Console.WriteLine(watch.Elapsed);
            }
            public void TestStatic(DataTable dt)
            {
                var watch = Stopwatch.StartNew();
                watch.Start();
    
                for (int i = 0; i < 10000; i++)
                {
                    var userlist = convert(dt);
                }
                watch.Stop();
                Console.WriteLine(watch.Elapsed);
            }
    
            public List<UserInfo> convert(DataTable dt)
            {
                List<UserInfo> list = new List<UserInfo>();
                foreach (DataRow row in dt.Rows)
                {
                    var user = new UserInfo(row["ID"].ToString())
                    { 
                        IsAnonymous = bool.Parse(row["IsAnonymous"].ToString()),
                        LastActiveDate = DateTime.Parse(row["LastActiveDate"].ToString())
                    };
                }
                return list;
            }
        }
        public class UserInfo
        {
            [DBColumn(DbName = "ID", Storage = "_UserID")]
            public Guid UserID { get { return _UserID; } }
            [DBColumn]
            public bool  IsAnonymous { get; set; }
            [DBColumn]
            public DateTime LastActiveDate { get; set; }
    
            private Guid _UserID;
    
            public UserInfo() { }
            public UserInfo(Guid userId)
            {
                _UserID = userId;
            }
            public UserInfo(string userId)
            {
                _UserID =Guid.Parse(userId);
            }
        }

    动态反射转换和硬编码相比有虽然几倍的差距,不过对于数据交换不是很频繁的情况下,绝对时间差距还是不大的

    使用这个辅助类,或者适当改造,就可以实现一般ORM的Query<T>的效果

  • 相关阅读:
    如何为你的Airtest报告自定义名称
    Go打包构建 生成32位64位应用程序 加入前端项目
    DNS解析与DNS缓存清理
    sharepoint2013安装记录
    C# winform自托管WebApi及身份信息加密、Basic验证、Http Message Handler、跨域配置
    IM扫码登录技术专题(四):你真的了解二维码吗?刨根问底、一文掌握!
    IM开发干货分享:万字长文,详解IM“消息“列表卡顿优化实践
    阿里IM技术分享(五):闲鱼亿级IM消息系统的及时性优化实践
    使用oracle序列+oracle定时任务获取每月从1开始的流水码
    为什么我的数据库查询越来越慢
  • 原文地址:https://www.cnblogs.com/FlyCat/p/2613205.html
Copyright © 2011-2022 走看看