zoukankan      html  css  js  c++  java
  • DataRow转换对象,对象类型可为空!

    我们知道在C#中,引用类型可以为null,而值类型不可以为null,就是值类型必须要有值。msdn上面的解释是值类型没有足够的空量来表示空值,它的容量只够表示适合该类型的值,没有多余的容量。而数据库中(比如sqlserver)中,任何类型的值都是可以为null的,这就给我们在往数据库中插入值带来麻烦了,比如要往数据库中的int字段中插入一个null值,而C#在2.0之前,是不可能给一个int类型的变量赋于null的。

    为了解决这个问题,C#引入了Nullable类,该类为值类型赋于null值提供了支持,如果我们要为一个int类型赋于null值,那么我们就可以声明该类型为Nullable,也可以直接缩写为int?,这就是我们在C#2.0后版本中看到的大量可为空的值类型声明方式。

    基础基元类型的概念:
    可空类型的原类型称之为该类型的基础基元类型,比如我们声明了变量int?,那么我们就称int为int?的基础基元类型。

    明白了这些概念后,现在假设我们要写一个方法,该方法要支持将一个object类型的值转换为任何可能转换的类型。
    该类有两个参数,值value,类型convertsionType,
    如果不支持可空类型,那么该方法很好实现,如下:
    public static object ChanageType(object value, Type convertsionType)
    {
    return Convert.ChangeType(value, convertsionType);
    }

    但是在开发过程中经常会遇到对象的属性为空,例:int?;

    这时如果convertsionType为可空类型,该方法就会报类似如下错误了:
    从“System.String”到“System.Nullable`1[[System.Int32, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]”的强制转换无效。

    这时候从DataRow转换Model时就必须改写网上的方法了。

     /// <summary>
        /// dataRow转换成对象
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="dr"></param>
        /// <returns></returns>
        public static class DataRowConvertToModelClass
        {
            /// <summary>
            /// dataRow转换成对象
            /// </summary>
            /// <typeparam name="T"></typeparam>
            /// <param name="dr"></param>
            /// <returns></returns>
            public static T DataRowConvertToModel<T>(this DataRow dr)
            {
                T t = Activator.CreateInstance<T>(); //创建实例           
                PropertyInfo[] pi = t.GetType().GetProperties();//取类的属性
                //属性赋值
                foreach (PropertyInfo p in pi)
                {
                    if (dr.Table.Columns.Contains(p.Name) && !string.IsNullOrWhiteSpace(dr[p.Name].ToString()))
                    {
                        //p.SetValue(t, "7".ConvertTo<Nullable<int>>(), null);
                        //p.SetValue(t, Convert.ChangeType(dr[p.Name], p.PropertyType), null);
                        //p.SetValue(t, Convert.ChangeType(dr[p.Name], p.PropertyType), null);
    
    
                        p.SetValue(t, chanageType(dr[p.Name], p.PropertyType), null);
                    }
                }
    
                return t; //Return
            }
            /// <summary>
            /// 数据转换为指定类型,支持对可空类型(Nullable类)转换
            /// </summary>
            /// <param name="value"></param>
            /// <param name="convertsionType"></param>
            /// <returns></returns>
            public static object chanageType(this object value, Type convertsionType)
            {
                //判断convertsionType类型是否为泛型,因为nullable是泛型类,
                if (convertsionType.IsGenericType &&
                    //判断convertsionType是否为nullable泛型类
                    convertsionType.GetGenericTypeDefinition().Equals(typeof(Nullable<>)))
                {
                    if (value == null || value.ToString().Length == 0)
                    {
                        return null;
                    }
    
                    //如果convertsionType为nullable类,声明一个NullableConverter类,该类提供从Nullable类到基础基元类型的转换
                    NullableConverter nullableConverter = new NullableConverter(convertsionType);
                    //将convertsionType转换为nullable对的基础基元类型
                    convertsionType = nullableConverter.UnderlyingType;
                }
                return Convert.ChangeType(value, convertsionType);
            }
        }

    调用时:

    WorkBillList billMode = DataRowConvertToModelClass.DataRowConvertToModel<WorkBillList>(workBill_dr);
  • 相关阅读:
    基于redis集群实现的分布式锁,可用于秒杀商品的库存数量管理,有測试代码(何志雄)
    VC断点失败的原因之中的一个
    由易到难学习递归的精华
    【特征检測】BRIEF特征点描写叙述算法
    POJ 2386 Lake Counting
    Design Pattern 设计模式1
    使用 InstallShield 制作 Delphi 软件安装包
    在64位系统上部署BDE的要点
    SQL SERVER 存储过程中SELECT 返回值如何赋值给变量
    sql语句中的insert 和 insert into 的区别?into有什么用?
  • 原文地址:https://www.cnblogs.com/TheBob/p/7451917.html
Copyright © 2011-2022 走看看