zoukankan      html  css  js  c++  java
  • 【原创】编程日记之——如何对DataSet进行强类型化

    前言

    在项目中经常需要用到DataSet来存放数据,但是一直觉得从数据集中获取数据使用是一件很难受的事情,特别是当需要用到强类型数据的时候,就想到了动手写个方法来实现。

    正文

    废话不多说,直接上代码吧:

       /// <summary>
            /// 将数据集强类型化
            /// </summary>
            /// <typeparam name="T">转换类型</typeparam>
            /// <param name="dataSet">数据源</param>
            /// <param name="tableIndex">需要转换表的索引</param>
            /// <returns>泛型集合</returns>
            public static IList<T> ToList<T>(this DataSet dataSet, int tableIndex)
            {
                //确认参数有效
                if (dataSet == null || dataSet.Tables.Count <= 0 || tableIndex < 0||dataSet.Tables.Count <= tableIndex)
                    return null;
    
                DataTable dt = dataSet.Tables[tableIndex];
    
    
                IList<T> list = new List<T>();
                for (int i = 0; i < dt.Rows.Count; i++)
                {
    
                    //创建泛型对象
                    T _t = Activator.CreateInstance<T>();
                    //获取对象所有属性
                    PropertyInfo[] propertyInfo = _t.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public);
                    for (int j = 0; j < dt.Columns.Count; j++)
                    {
                        foreach (PropertyInfo info in propertyInfo)
                        {
                            //属性名称和列名相同时赋值
                            if (dt.Columns[j].ColumnName.ToUpper().Equals(info.Name.ToUpper()))
                            {
                                if (dt.Rows[i][j] != DBNull.Value)
                                {
                                    info.SetValue(_t, dt.Rows[i][j].ConvertDataTo(info.PropertyType), null);
                                }
                                else
                                {
                                    info.SetValue(_t, null, null);
                                }
                                break;
                            }
                        }
                    }
                    list.Add(_t);
                }
                return list;
            }

    在需要给属性赋值的时候,为了避免数据集中的字段名与用户定义的Model属性名一致而类型不一致的问题,我又写了个方法,用来把对象进行类型转换:

            public static object ConvertDataTo(this object obj,Type type) 
            {
                if (obj.GetType().Equals(type))
                {
                    return obj;
                }
                else
                {
                    try
                    {
                        if (type == typeof(string)) { return obj.ToString(); }
                        MethodInfo parseMethod = null;
                        foreach (MethodInfo mi in type.GetMethods(BindingFlags.Static | BindingFlags.Public))
                        {
                            if (mi.Name == "Parse" && mi.GetParameters().Length == 1)
                            { parseMethod = mi; break; }
                        }
                        if (parseMethod == null)
                        {
                            return null;
                        }
                        return parseMethod.Invoke(null, new object[] { obj }); 
                    }
                    catch 
                    {
                        return null;
                    }
                }
            }

    其实这么写是比较偷懒的写法,用了这么多反射, 于是想到做一下性能测试,我建的MVC项目,看一下测试结果:

      public ActionResult Index()
            {
    
                DataSet ds = new DataSet();
                DataTable dt = new DataTable();
                dt.Columns.Add("resourcename1", typeof(string));
                dt.Columns.Add("resourcename2", typeof(string));
                dt.Columns.Add("resourcename3", typeof(string));
                dt.Columns.Add("resourcename4", typeof(string));
                dt.Columns.Add("resourcename5", typeof(string));
                dt.Columns.Add("fitsex1", typeof(int));
                dt.Columns.Add("fitsex2", typeof(int));
                dt.Columns.Add("fitsex3", typeof(int));
                dt.Columns.Add("fitsex4", typeof(int));
                dt.Columns.Add("fitsex5", typeof(int));
                for (int i = 0; i < 5000; i++)
                {
                    DataRow row = dt.NewRow();
                    row[0] = "王虎" + i.ToString();
                    row[1] = "王虎" + i.ToString();
                    row[2] = "王虎" + i.ToString();
                    row[3] = "王虎" + i.ToString();
                    row[4] = "王虎" + i.ToString();
                    row[5] = i;
                    row[6] = i;
                    row[7] = i;
                    row[8] = i;
                    row[9] = i;
                    dt.Rows.Add(row);
                }
                ds.Tables.Add(dt);
    
                var watch = new Stopwatch();
                watch.Start();
                var ModelList = ds.ToList<Model_Resource>(0);
    
                watch.Stop();
                ViewData["Message"] = string.Format("ModelList.count={0},Elapsed Milliseconds:{1}", ModelList.Count.ToString(),watch.ElapsedMilliseconds.ToString());
    
                return View();
            }

    我使用的类定义如下:

      /// <summary>
        /// 实体类Resource 。(属性说明自动提取数据库字段的描述信息)
        /// </summary>
        [Serializable]
        public class Model_Resource
        {
            public Model_Resource()
            { }
            #region Model
          
          
            /// <summary>
            /// 资源标准名称
            /// </summary>
            public string ResourceName1
            {
                get;
                set;
            }
            /// <summary>
            /// 资源标准名称
            /// </summary>
            public string ResourceName2
            {
                get;
                set;
            }
            /// <summary>
            /// 资源标准名称
            /// </summary>
            public string ResourceName3
            {
                get;
                set;
            }
            /// <summary>
            /// 资源标准名称
            /// </summary>
            public string ResourceName4
            {
                get;
                set;
            }
    
            /// <summary>
            /// 资源标准名称
            /// </summary>
            public string ResourceName5
            {
                get;
                set;
            }
            /// <summary>
            /// 适合的性别 1 男 2 女 3 均可
            /// </summary>
            public string FitSex1
            {
                get;
                set;
            }
            /// <summary>
            /// 适合的性别 1 男 2 女 3 均可
            /// </summary>
            public string FitSex2
            {
                get;
                set;
            }
            /// <summary>
            /// 适合的性别 1 男 2 女 3 均可
            /// </summary>
            public string FitSex3
            {
                get;
                set;
            }
            /// <summary>
            /// 适合的性别 1 男 2 女 3 均可
            /// </summary>
            public string FitSex4
            {
                get;
                set;
            }
    
            /// <summary>
            /// 适合的性别 1 男 2 女 3 均可
            /// </summary>
            public string FitSex5
            {
                get;
                set;
            }
            #endregion Model
    
        }

    看一下测试结果:

    1

    后记

    性能上还可以通过缓存等机制优化一下,不过这方面已经有一些大牛做过了,以后有时间可以加进去。

    欢迎拍砖~


    本博客文章若非标记转载,均为原创,转载请注明出处~


  • 相关阅读:
    音频波谱通用类|超酷的说
    跟随鼠标的星星实例
    AS3放大镜工具类
    caurina缓动类
    AS3中 is,as,typeof的区别
    Loader ,URLLoader ,URLStream的区别
    (转)AS3正则:元子符,元序列,标志,数量表达符
    动态绘制扇形实例
    AS3.0绘图API
    as3效率优化
  • 原文地址:https://www.cnblogs.com/wbpmrck/p/2013730.html
Copyright © 2011-2022 走看看