参数化查询,有什么传递null的好办法吗?

白衣如花 2017-09-06 03:50:35
类有很多成员,一开始用'{0}','{1}'的形式来插入,则报空引用异常,而且插入到数据库也不是null,而是''

然后想着用参数化来插入,结果报 @xxx 为null

查资料说数据库的null对应C#DBNull.Value

于是代码写出这样 new SqlParameter("@abc", (object)cls.abc?? DBNull.Value)

丑的一逼,还要改n多参数,有什么其他好办法吗?
...全文
817 27 打赏 收藏 转发到动态 举报
写回复
用AI写文章
27 条回复
切换为时间正序
请发表友善的回复…
发表回复
lovezq85 2018-07-03
  • 打赏
  • 举报
回复
SqlParameter[] parameters = new SqlParameter[]
{
new SqlParameter ("@userId",SqlDbType.NVarChar,50){ Value=DBNull.Value},
new SqlParameter ("@password",SqlDbType.VarChar,50){ Value=DBNull.Value},
new SqlParameter ("@realName",SqlDbType.NVarChar,50){Value=DBNull.Value}
};
这样做好看吧!!!
白衣如花 2017-09-13
  • 打赏
  • 举报
回复
foreach (SqlParameter para in cmd.Parameters)
{
    if ((para.Direction == ParameterDirection.Output || para.Direction == ParameterDirection.InputOutput) && para.Value == null)
        para.Value = DBNull.Value;
}
另一种解决方案共后人参考
白衣如花 2017-09-07
  • 打赏
  • 举报
回复
引用 22 楼 sp1234 的回复:
[quote=引用 21 楼 u012948520 的回复:]ull.GetDBParam恐怕不行。。。
我去,你可真晕哦! 你会手写 null.GetDBParam() 这种代码吗? 如果你手写 obj.GetDBParam() 这种代码,而 obj 变量可以引用为 null,那么就 OK 了。[/quote]哇!果然可以
ilikeff8 2017-09-07
  • 打赏
  • 举报
回复
建议用EF,可以少写不少需要注意这种细节的代码,已经帮你处理好了 如果要用ado.net,可以这样

        static void Main(string[] args)
        {
            CLS cls = new CLS
            {
                abc = null
            };

            using (SqlConnection sqlConnection = new SqlConnection("Data Source=.;Initial Catalog=test;Integrated Security=True"))
            {
                sqlConnection.Open();

                SqlCommand sqlCommand = new SqlCommand("INSERT INTO TESTA (A,B) VALUES(@A,@B)", sqlConnection);
                sqlCommand.Parameters.AddWithValue("A", 1);
                sqlCommand.Parameters.AddWithValue("B", GetDBValue(cls?.abc));
                sqlCommand.ExecuteNonQuery();
            }
        }

        static public object GetDBValue(object obj)
        {
            return obj ?? DBNull.Value;
        }

        public class CLS
        {
            public int? abc;
        }
实际ado.net的项目里,一般是会有通用动态创建SQL语句方法的,例如插入,如果参数为null,那该字段就直接不写入SQL语句,也不赋值,也就无所谓是不是要转换成dbnull
  • 打赏
  • 举报
回复
引用 21 楼 u012948520 的回复:
ull.GetDBParam恐怕不行。。。
我去,你可真晕哦! 你会手写 null.GetDBParam() 这种代码吗? 如果你手写 obj.GetDBParam() 这种代码,而 obj 变量可以引用为 null,那么就 OK 了。
白衣如花 2017-09-07
  • 打赏
  • 举报
回复
引用 20 楼 sp1234 的回复:
[quote=引用 18 楼 u012948520 的回复:] [quote=引用 16 楼 sp1234 的回复:] 你可以把这一句话封装为你自己的方法啊?!!
嗯,我这么改了一下,代码好看多了
        public static object GetDBParam(object value)
        {
            if (value == null)
                return DBNull.Value;
            else
                return value;
        }
new SqlParameter("@Code", MyHelper.GetDBParam(report.Code))
[/quote] 如果你采用“扩展方法”技术,例如定义一个

    public static object GetDBParam(this object value)
就是多写个 this,那么你就可以写
new SqlParameter("@Code", report.Code.GetDBParam())
你已经为任意的 object 都添加了一个 GetDBParam 扩展方法。这才真的“好看”啊。[/quote]null.GetDBParam恐怕不行。。。
  • 打赏
  • 举报
回复
引用 18 楼 u012948520 的回复:
[quote=引用 16 楼 sp1234 的回复:] 你可以把这一句话封装为你自己的方法啊?!!
嗯,我这么改了一下,代码好看多了
        public static object GetDBParam(object value)
        {
            if (value == null)
                return DBNull.Value;
            else
                return value;
        }
new SqlParameter("@Code", MyHelper.GetDBParam(report.Code))
[/quote] 如果你采用“扩展方法”技术,例如定义一个

    public static object GetDBParam(this object value)
就是多写个 this,那么你就可以写
new SqlParameter("@Code", report.Code.GetDBParam())
你已经为任意的 object 都添加了一个 GetDBParam 扩展方法。这才真的“好看”啊。
白衣如花 2017-09-07
  • 打赏
  • 举报
回复
引用 17 楼 closurer 的回复:
分享我的做法,写一个类,把 null 隐式转换为 DBNull 迟些时候我会开源出来。
支持
白衣如花 2017-09-07
  • 打赏
  • 举报
回复
引用 16 楼 sp1234 的回复:
你可以把这一句话封装为你自己的方法啊?!!
嗯,我这么改了一下,代码好看多了
        public static object GetDBParam(object value)
        {
            if (value == null)
                return DBNull.Value;
            else
                return value;
        }
new SqlParameter("@Code", MyHelper.GetDBParam(report.Code))
weixin_40147879 2017-09-07
  • 打赏
  • 举报
回复
好难啊看起来
闭包客 2017-09-06
  • 打赏
  • 举报
回复
分享我的做法,写一个类,把 null 隐式转换为 DBNull

迟些时候我会开源出来。
  • 打赏
  • 举报
回复
引用 楼主 u012948520 的回复:
查资料说数据库的null对应C#DBNull.Value 于是代码写出这样 new SqlParameter("@abc", (object)cls.abc?? DBNull.Value) 丑的一逼,还要改n多参数,有什么其他好办法吗?
你可以把这一句话封装为你自己的方法啊?!!
吉普赛的歌 2017-09-06
  • 打赏
  • 举报
回复
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.SqlClient;
using System.Data;

namespace ConsoleApplication7
{
    class Program
    {
        static void Main(string[] args)
        {
            //-------------- 明确指定参数的类型,有利于执行计划的准确生成和重用 -------------------------
            //如果你不怕麻烦,甚至可以指定字符串的长度
            //搜索时的参数 (主要特点是 字符串的空串可以认为是 NULL )
            SqlParameter[] spArr = new SqlParameter[] 
            {
                SetSqlParameter("@beginTime",null,SqlDbType.DateTime),
                SetSqlParameter("@endTime",null,SqlDbType.DateTime),
                SetSqlParameter("@name","小明", SqlDbType.NVarChar),
                SetSqlParameter("@desc","", SqlDbType.NVarChar),
                SetSqlParameter("@enabled","", SqlDbType.Bit)
            };

            //插入时的参数 (主要特点是 字符串的空串不能认为是 NULL )
            SqlParameter[] spArr2 = new SqlParameter[] 
            {
                SetSqlParameter("@beginTime", DateTime.Parse("2017-09-01") ,SqlDbType.DateTime),
                SetSqlParameter("@endTime", null , SqlDbType.DateTime),
                SetSqlParameter("@name","小明", false, SqlDbType.NVarChar),
                SetSqlParameter("@desc","插入参数", false, SqlDbType.NVarChar),
                SetSqlParameter("@enabled", true, SqlDbType.Bit)
            };

        }

        //---------------------  下面的方法, 你可以加入到你的 SqlHelper --------------------------------
        /// <summary>
        /// 设置Sql参数
        /// </summary>
        /// <param name="parameterName"></param>
        /// <param name="value"></param>
        /// <param name="stringEmptyIsNull"></param>
        /// <param name="dbType"></param>
        /// <returns></returns>
        public static SqlParameter SetSqlParameter(string parameterName, object value, SqlDbType dbType)
        {
            return SetSqlParameter(parameterName, value, true, dbType);
        }


        /// <summary>
        /// 设置Sql参数
        /// </summary>
        /// <param name="parameterName"></param>
        /// <param name="value"></param>
        /// <param name="stringEmptyIsNull"></param>
        /// <param name="dbType"></param>
        /// <returns></returns>
        public static SqlParameter SetSqlParameter(string parameterName, object value, bool stringEmptyIsNull, SqlDbType dbType)
        {
            if (value == null || (string.IsNullOrEmpty(value.ToString()) && stringEmptyIsNull))
            {
                return new SqlParameter(parameterName, DBNull.Value);
            }
            SqlParameter sp = new SqlParameter(parameterName, value);
            sp.SqlDbType = dbType;
            return sp;
        }
    }
}
exception92 2017-09-06
  • 打赏
  • 举报
回复
引用 12 楼 u012948520 的回复:
引用 10 楼 duanzi_peng 的回复:
貌似只能用DBNull.Value了,至于 可空类型,例如:int? 这样的也就不能使用。
还是EF大法好
是的。 现在ORM框架这么多,也比较成熟。其实我看见那些个拼接的sql都头疼,还有那些个单引号,双引号,花括号交织在一起。
exception92 2017-09-06
  • 打赏
  • 举报
回复
引用 12 楼 u012948520 的回复:
引用 10 楼 duanzi_peng 的回复:
貌似只能用DBNull.Value了,至于 可空类型,例如:int? 这样的也就不能使用。
还是EF大法好
国外也是DBNull, https://stackoverflow.com/questions/21622741/how-to-assign-a-value-to-sqlparameter-null-values-without-checking-for-null-or-0 https://stackoverflow.com/questions/13981281/best-method-of-assigning-null-value-to-sqlparameter
白衣如花 2017-09-06
  • 打赏
  • 举报
回复
引用 10 楼 duanzi_peng 的回复:
貌似只能用DBNull.Value了,至于 可空类型,例如:int? 这样的也就不能使用。
还是EF大法好
白衣如花 2017-09-06
  • 打赏
  • 举报
回复
引用 1 楼 yxhkami 的回复:
在数据库字段允许为null。不给值默认就是null把
是的。但是我写插入为了方便,是直接写的insert into xxx values (....) 确实用每一个属性做null判断然后拼接sql是个可行方案 insert into xxx (...) values (...)l
exception92 2017-09-06
  • 打赏
  • 举报
回复
引用 7 楼 u012948520 的回复:
[quote=引用 2 楼 duanzi_peng 的回复:] new SqlParameter("@abc", (object)cls.abc?? DBNull.Value) -》
new SqlParameter("@abc", cls.abc == null ? " " : cls.abc);
这个不好 [nchar](20) NULL 的字段,本来应该插入null的,你这么写就插入了""了 [datetime] NULL的字段,则插入了1900-01-01 00:00:00.000[/quote] 貌似只能用DBNull.Value了,至于 可空类型,例如:int? 这样的也就不能使用。
秋的红果实 2017-09-06
  • 打赏
  • 举报
回复
我一般不在sql参数上处理,而是在赋值时处理,例如 command.Parameter.Add(new Parameter("@sql",nchar,100).value=textBox1.Text.Trim()=="" (object)Dbnull.value:textBox1.Text.Trim(); 手工敲得 这样,需求变动时,只改动程序就可以了,无需改动sql端
白衣如花 2017-09-06
  • 打赏
  • 举报
回复
引用 6 楼 hanjun0612 的回复:
[quote=引用 5 楼 u012948520 的回复:] 主要是用到了装箱,很不爽。。。
如果从代码简洁来说,??看起来好点, 如果从装箱的问题来说,那么就写if else。代码多点。 我一般都是写if else的。 三元表达式都不能用。 以前也纠结过这个问题,但是找了很久,也没看到好的解决方案。 [/quote]属性过多。。。if else懒一个个得写。。。先这样吧
加载更多回复(7)

110,566

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧