C#关于 DBNull和 Null , ?和 ?? 的区别和应用

版权声明:未经本人允许,必须声明原文转载地址和作者! https://blog.csdn.net/liuchang19950703/article/details/88050162

一:关于 DBNull和 Null 的区别

1.查询数据时:DBNull是C#查询数据库字段的NULL值的一个类型,该类型不能直接赋值给C#实体类的属性,会造成转换报错,因此需要转换成C#的NULL再进行赋值,

2.插入或者更新数据时:C#插入或者更改数据库字段时,C#的NULl也要转换成DBNull再对数据库进行操作,否则也会造成转换报错

注意:这里要注意实体类中的【DateTime】字段,该字段如果不赋值会默认是【0001/01/01 00:00L00】,数据库不能识别这个时间,会报转换错误,所以在实体类中的【DateTime】字段中间加上 "?". 

附上代码:

1.查询数据:

        /// <summary>
        /// 获取所有对象
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public List<T> GetAllList<T>() where T : BaseModel
        {
            try
            {
                List<T> list = new List<T>();
                Type type = typeof(T);
                StringBuilder sql = new StringBuilder();
                string colNameStr = string.Join(",", type.GetProperties().Select(a => string.Format("[{0}]", AttributeHelp.GetColNameByProp(a))));
                sql.AppendFormat(" select {0} from {1} ", colNameStr, type.Name);
                using (conn = new SqlConnection(_connStr))
                {
                    SqlCommand cmd = new SqlCommand(sql.ToString(), conn);
                    conn.Open();
                    SqlDataReader reader = cmd.ExecuteReader();
                    list = GetListBySqlDataReader<T>(reader);
                }
                return list;
            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                conn.Close();
            }
        }

        /// <summary>
        /// 查询辅助类
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="reader"></param>
        /// <returns></returns>
        public List<T> GetListBySqlDataReader<T>(SqlDataReader reader)
        {
            Type type = typeof(T);
            List<T> list = new List<T>();
            while (reader.Read())
            {
                T t = (T)Activator.CreateInstance(type);
                foreach (var prop in type.GetProperties())
                {
                    prop.SetValue(t, reader[AttributeHelp.GetColNameByProp(prop)] is DBNull ? null : reader[AttributeHelp.GetColNameByProp(prop)]);
                }
                list.Add(t);
            }
            return list;
        }

2.更新数据:

        /// <summary>
        /// 通过id更新单个对象
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="id"></param>
        /// <returns></returns>
        public bool Update<T>(T t) where T : BaseModel
        {
            try
            {
                Type type = typeof(T);
                var propArr = type.GetProperties().Where(a => a.Name != "id");
                string paramStr = string.Join(",", propArr.Select(a => string.Format(" [{0}]=@{1} ", AttributeHelp.GetColNameByProp(a), AttributeHelp.GetColNameByProp(a))));
                StringBuilder sql = new StringBuilder();
                sql.AppendFormat("update {0} set {1} where id={2} ", type.Name, paramStr, t.id);
                using (conn = new SqlConnection(_connStr))
                {
                    conn.Open();
                    SqlParameter[] paraArr = propArr.Select(a => new SqlParameter { ParameterName = AttributeHelp.GetColNameByProp(a), Value = (a.GetValue(t) ?? System.DBNull.Value) }).ToArray();
                    SqlCommand cmd = new SqlCommand(sql.ToString(), conn);
                    cmd.Parameters.AddRange(paraArr);
                    return cmd.ExecuteNonQuery() > 0;
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                conn.Close();
            }
        }



  public class Company : BaseModel
    {

        public string cp_name { get; set; }

        [AttributeByColName("desc")]
        public string cp_desc { get; set; }
        public string create_user { get; set; }
        public string modify_user { get; set; }
        public string delete_user { get; set; }
        public DateTime? create_time { get; set; }
        public DateTime? modify_time { get; set; }
        public DateTime? delete_time { get; set; }
        public bool is_deleted { get; set; }
    }

二:关于?和 ?? 的区别

1. 可空类型修饰符(?):
引用类型可以使用空引用表示一个不存在的值,而值类型通常不能表示为空。
例如:string str=null; 是正确的,int i=null; 编译器就会报错。
为了使值类型也可为空,就可以使用可空类型,即用可空类型修饰符"?"来表示,表现形式为"T?"
例如:int? 表示可空的整形,DateTime? 表示可为空的时间。
T? 其实是System.Nullable(泛型结构)的缩写形式,也就意味着当你用到T?时编译器编译 时会把T?编译成System.Nullable的形式。
例如:int?,编译后便是System.Nullable的形式。

2. 三元(运算符)表达式(?:):
例如:x?y:z 表示如果表达式x为true,则返回y;如果x为false,则返回z,是省略if{}else{}的简单形式。

3. 空合并运算符(??):
用于定义可空类型和引用类型的默认值。如果此运算符的左操作数不为null,则此运算符将返回左操作数,否则返回右操作数。
例如:a??b 当a为null时则返回b,a不为null时则返回a本身。
空合并运算符为右结合运算符,即操作时从右向左进行组合的。如,“a??b??c”的形式按“a??(b??c)”计算。

猜你喜欢

转载自blog.csdn.net/liuchang19950703/article/details/88050162