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

    后记

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

    欢迎拍砖~


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


  • 相关阅读:
    显示文件本地文件夹
    Select Dependencies选择依赖项
    搜索小技巧
    783. Minimum Distance Between BST Nodes BST节点之间的最小距离
    5. Longest Palindromic Substring 最长的回文子串
    12. Integer to Roman 整数转罗马数字
    3. Longest Substring Without Repeating Characters 最长的子串不重复字符
    539. Minimum Time Difference 最小时差
    43. Multiply Strings 字符串相乘
    445. Add Two Numbers II 两个数字相加2
  • 原文地址:https://www.cnblogs.com/wbpmrck/p/2013730.html
Copyright © 2011-2022 走看看