1datatable 创建可空类型 2 匿名类型创建可空 3 匿名类型设置为泛型(最简单的办法是定义一个类) 也可以反射在IL里面创建类 动态产生一个类型,并且动态写入 IL 代码产生属性。 比较复杂 DBNull与Null的区别

dataTable.Columns.Add("Dt", typeof(Nullable<DateTime>)); 会报错 DataSet 不支持 System.Nullable<>。

要用这个 dataTable.Columns.Add("Dt", typeof(Nullable<DateTime>).GetGenericArguments()[0]);

 

var entity = new { Name = "item", ID = 0, GuidType = Guid.Empty, Dt = (Nullable<DateTime>)DateTime.Now };   这个
var entity2 = new { Name = "item", ID = 0, GuidType = Guid.Empty, Dt = DBNull.Value };
var entity3 = new { Name = "item", ID = 0, GuidType = Guid.Empty, Dt = (Nullable<DateTime>)null };  这个

 

using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApplication24
{
    enum A
    {
        A, b, c, d, e, f
    }
    class Program
    {
        public static IList FromTable(Type GenericType, DataTable dataTable)
        {
            Type typeMaster = typeof(List<>);
            Type listType = typeMaster.MakeGenericType(GenericType);
            IList list = Activator.CreateInstance(listType) as IList;
            if (dataTable == null || dataTable.Rows.Count == 0)
                return list;
            var constructor = GenericType.GetConstructors(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)
                           .OrderBy(c => c.GetParameters().Length).First();
            var parameters = constructor.GetParameters();
            var values = new object[parameters.Length];
            foreach (DataRow dr in dataTable.Rows)
            {
                int index = 0;
                foreach (ParameterInfo item in parameters)
                {
                    object itemValue = null;
                    if (dr[item.Name] != null && dr[item.Name] != DBNull.Value)
                    {
                        itemValue = Convert.ChangeType(dr[item.Name], item.ParameterType);
                    }
                    values[index++] = itemValue;
                }
                list.Add(constructor.Invoke(values));
            }
            return list;
        }
        public delegate object[] CreateRowDelegate<T>(T t);
        //public static DataTable ToDataTable<T>(this IEnumerable<T> varlist, CreateRowDelegate<T> fn)
        //{
        //    DataTable dtReturn = new DataTable();
        //    // column names
        //    PropertyInfo[] oProps = null;
        //    // Could add a check to verify that there is an element 0
        //    foreach (T rec in varlist)
        //    {
        //        // Use reflection to get property names, to create table, Only first time, others will follow
        //        if (oProps == null)
        //        {
        //            oProps = ((Type)rec.GetType()).GetProperties();
        //            foreach (PropertyInfo pi in oProps)
        //            {
        //                Type colType = pi.PropertyType; if ((colType.IsGenericType) && (colType.GetGenericTypeDefinition() == typeof(Nullable<>)))
        //                {
        //                    colType = colType.GetGenericArguments()[0];
        //                }
        //                dtReturn.Columns.Add(new DataColumn(pi.Name, colType));
        //            }
        //        }
        //        DataRow dr = dtReturn.NewRow(); foreach (PropertyInfo pi in oProps)
        //        {
        //            dr[pi.Name] = pi.GetValue(rec, null) == null ? DBNull.Value : pi.GetValue(rec, null);
        //        }
        //        dtReturn.Rows.Add(dr);
        //    }
        //    return (dtReturn);
        //}

        static public object ChangeType(object value, Type type)
        {
            if (value == null && type.IsGenericType) return Activator.CreateInstance(type);
            if (value == null) return null;
            if (value == DBNull.Value) return null;
            if (type == value.GetType()) return value;
            if (type.IsEnum)
            {
                if (value is string)
                    return Enum.Parse(type, value as string);
                else
                    return Enum.ToObject(type, value);
            }
            if (!type.IsInterface && type.IsGenericType)
            {
                Type innerType = type.GetGenericArguments()[0];
                object innerValue = ChangeType(value, innerType);
                return Activator.CreateInstance(type, new object[] { innerValue });
            }
            if (value is string && type == typeof(Guid)) return new Guid(value as string);
            if (value is string && type == typeof(Version)) return new Version(value as string);
            if (!(value is IConvertible)) return value;
            return Convert.ChangeType(value, type);
        }

        public static List<T> GetEntities<T>(DataTable table) where T : new()
        {
            List<T> entities = new List<T>();
            try
            {
                foreach (DataRow row in table.Rows)
                {
                    T entity = new T();
                    foreach (var item in entity.GetType().GetProperties())
                    {
                        if (table.Columns.Contains(item.Name))
                            item.SetValue(entity, ChangeType(row[item.Name], item.PropertyType), null);
                    }
                    entities.Add(entity);
                }
            }
            catch { }
            return entities;
        }


        static void Main(string[] args)
        {
            var entity = new { Name = "item", ID = 0, GuidType = Guid.Empty, Dt = (Nullable<DateTime>)DateTime.Now };   // 可空
            var entity2 = new { Name = "item", ID = 0, GuidType = Guid.Empty, Dt = DBNull.Value };    // System.DBNull 类型
            var entity3 = new { Name = "item", ID = 0, GuidType = Guid.Empty, Dt = (Nullable<DateTime>)null };  //// 可空
            //var entity4 = new { Name = "item", ID = 0, GuidType = Guid.Empty, Dt = null }; //错误    1    不能将“<null>”赋值给匿名类型属性    


            DataTable dataTable = new DataTable();
            dataTable.Columns.Add("Name", typeof(string));
            dataTable.Columns.Add("ID", typeof(int));
            dataTable.Columns.Add("GuidType", typeof(Guid));
            //dataTable.Columns.Add("Dt", typeof(Nullable<DateTime>));
            dataTable.Columns.Add("Dt", typeof(Nullable<DateTime>).GetGenericArguments()[0]);


            for (int i = 0; i < 10; i++)
            {

                DataRow dr = dataTable.NewRow();
                dr["Name"] = "STRING" + i;
                dr["ID"] = i;
                if (i % 2 == 0)
                    dr["GuidType"] = Guid.Empty;
                else
                {
                    dr["GuidType"] = DBNull.Value;   // dataTable 行列 里面数据 存的都是 object 类型的 所以可以  DBNull.Value 替代 可 null
                }
                if (i == 0)
                {
                    dr["Dt"] = DateTime.Now;
                }
                else
                {
                    //dr["Dt"] = null;    //不能将 Column“Dt”设置为 null。请改用 DBNull。      DBNull 是 类 (DBNull类)  也属于object类型
                    dr["Dt"] = DBNull.Value;                                          //   null 为 空指针 空引用 不是类
                }
                dataTable.Rows.Add(dr);
            }
            object op = DBNull.Value;
            object op2 = null;
            Console.WriteLine(op is object);
            Console.WriteLine(op2 is object);
            //IList list = FromTable(entity.GetType(), dataTable);
            //IList list = FromTable(entity.GetType(), dataTable);
            Type o = entity.GetType();

            var list = GetEntities<As>(dataTable);
            Console.WriteLine(((A)1).ToString());
        }
    }
    class As
    {//            var entity = new { Name = "item", ID = 0, GuidType = Guid.Empty, Dt = (Nullable<DateTime>)DateTime.Now };
        public string Name
        {
            get;
            set;
        }
        public int ID
        {
            get;
            set;
        }
        public Guid? GuidType
        {
            get;
            set;
        }
        public DateTime? Dt
        {
            get;
            set;
        }
    }

}

 

 

 

DBNull与Null的区别

在其他网站上看见的,感觉讲的不错,链接地址:http://www.cnblogs.com/muou/archive/2010/03/23/1692391.html

Null是.net中无效的对象引用。

DBNull是一个类。DBNull.Value是它唯一的实例。它指数据库中数据为空(<NULL>)时,在.net中的值。

null表示一个对象的指向无效,即该对象为空对象。

DBNull.Value表示一个对象在数据库中的值为空,或者说未初始化,DBNull.Value对象是指向有效的对象。 

DBNull在DotNet是单独的一个类型 System.DBNull 。它只有一个值 DBNull.Value 。DBNull 直接继承 Object ,所以 DBNull 不是 string , 不是 int , 也不是 DateTime 。。。

但是为什么 DBNull 可以表示数据库中的字符串,数字,或日期呢?原因是DotNet储存这些数据的类(DataRow等)都是以 object 的形式来储存数据的。

对于 DataRow , 它的 row[column] 返回的值永远不为 null , 要么就是具体的为column 的类型的值 。要么就是 DBNull 。 所以 row[column].ToString() 这个写法永远不会在ToString那里发生NullReferenceException,但有可能抛下标越界的异常。

DBNull 实现了 IConvertible 。 但是,除了 ToString 是正常的外,其他的ToXXX都会抛出不能转换的错误。

在 IDbCommand(OleDbCommand,SqlCommand...) 的ExecuteScalar的返回值中,情况可以这样分析:

select 1 这样返回的object是 1
select null 这样返回的是DBNull.Value
select isnull(null,1) 返回的是 1
select top 0 id from table1 这样返回的值是null
select isnull(id,0) from table1 where 1=0 返回的值是null

这里 ExecuteScalar 的规则就是,返回第一列,第一行的数据。如果一行都没有,那么ExecuteScalar就返回null。如果有第一行,但是第一列为空,那么返回的是 DBNull 。如果第一列第一行不为空,那么ExecuteScalar就直接对应的DotNet的值。

规则就是这样的。这里容易犯的一个错误是,把ExecuteScalar返回DBNull与null的情况混淆,例如:

string username=cmd.ExecuteScalar().ToString();

除非你认为cmd执行后,肯定至少有一行数据,否则这里就会出错。

又或者 select id from usertable where username=@name 这样的sql语句,如果找不到记录,那么ExecuteScalar则会返回null,所以千万不要

int userid=Convert.ToInt32(cmd.ExecuteScalar());

或者你会这样写 SQL 语句:select isnull(id,0) from usertable where username=@name

但是 int userid=Convert.ToInt32(cmd.ExecuteScalar()); 依然会出错,因为上面的语句不成立时,仍然是不返回任何行。

对于IDbDataParameter(OleDDbParameter,SqlParameter..)的Value,如果为null,则代表该参数没有指定,或者是代表DEFAULT。如果为DBNull.Value,则代表SQL中的NULL

所以,如果你要调用存储过程,里面有默认参数 @val nvarchar(20)="AABB" , 
那么cmd.Parameters["@val"].Value=null 代表使用这个默认的 "AABB"
而cmd.Parameters["@val"].Value=DBNull.Value 代表使用NULL来传给 @val

你可以用Convert.IsDBNull来判断一个值是否DBNull。注意Convert.IsDBNull(null)是false,也就是说null跟DBNull.Value是不等的。

 

 

 

 

C# DBNull和null说明

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u011127019/article/details/53404745

null 是.net中无效的对象引用。在数据类型中,对于引用类型的默认只就是为null,表示当前变量不指向任何对象。也称空指针。

DBNull是一个类。DBNull.Value是它唯一的实例。继承自Object

它用来对应数据库的数据为空(<NULL>)时,在.Net中的对应值。

 

object obj1 = DBNull.Value;

它不是数据类型,只是用来对应数据库中为null的值,表示“不知道”。

 

例如:数据库一列是int类型,可空,如果在读取数据库是对于DataRow,返回的数据null对应的结果就是DBNull.Value,

它的row[column]返回的值永远不会为null,所以row[column].ToString()这个写法不会抛出NullReferenceException的空指针异常。

接着说,如果想向数据库中的int列的值插入NULL的话,在指定数据库参数@id的时候,如果参数的值应该是DBNull.Value而不是null,如果是null则数据库抛出异常“@xxx 没有指定值”。

 

DBNull 实现了 IConvertible 。 但是,除了 ToString 是正常的外,其他的ToXXX都会抛出不能转换的错误。

在 IDbCommand(OleDbCommand,SqlCommand...) 的ExecuteScalar的返回值中,情况可以这样分析:

select 1 这样返回的object是 1

select null 这样返回的是DBNull.Value

select isnull(null,1) 返回的是 1

select top 0 id from table1 这样返回的值是null

select isnull(id,0) from table1 where 1=0 返回的值是null

 

这里 ExecuteScalar 的规则就是,返回第一列,第一行的数据。如果一行都没有,那么ExecuteScalar就返回null。如果有第一行,但是第一列为空,那么返回的是 DBNull 。如果第一列第一行不为空,那么ExecuteScalar就直接对应的DotNet的值。

你可以用Convert.IsDBNull来判断一个值是否DBNull。注意Convert.IsDBNull(null)是false,

也就是说null跟DBNull.Value是不等的。

DBNull.Value,, 是适用于向数据库的表中插入空值。而 null,是指在程序中表示空引用。 或者对象为空。就是没有实例化。

row[column]的值为DBNull.Value的话,至少说明它是从数据库中取到值了,对应了数据库中的空值;但如果row[column]的值为null的话,说明没有从数据库中取到值。DBNull.Value是一个有着内存地址的具体类型的值,映射了数据库中的null值;而NULL则是空指向,不存在对应的内存地址。任何对象赋值为null后,内存就释放了。
---------------------
作者:beautifulsarah
来源:CSDN
原文:https://blog.csdn.net/beautifulsarah/article/details/54691670
版权声明:本文为博主原创文章,转载请附上博文链接!

posted @ 2018-10-26 11:34  ~雨落忧伤~  阅读(317)  评论(0编辑  收藏  举报