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>的效果

  • 相关阅读:
    (转)oracle 11g安装后用户名忘记怎么办
    svn
    (转)ublox公司AGPS解决方案简介
    转(Google 全国 地图 纠偏数据 偏移数据 火星坐标修正 方案 )
    (转)真实经纬度的最简单获得方法
    (转)64bit上安装32位oracle 10 g出现错误:无法定位承诺工序输入点 getprocessimagifilenamew 于动态链接库PSAPI.DLL
    转】PPT带备注演示(只有讲解者看到备注)[转载]
    iphone应用程序结构
    ObjC 初识
    并行编程(PLINQ)学习笔记
  • 原文地址:https://www.cnblogs.com/FlyCat/p/2613205.html
Copyright © 2011-2022 走看看