该文章同时解决了,如何向数据库中添加Null值,以及如何处理“参数化查询未提供参数”的错误。解决方案请看第二段折叠的代码。
背景:
在项目开发的过程中,往往需要根据实体的值来修改sql语句,比如说,有一个学生类Stu,代码如下:
1 public class Student 2 { 3 public int ID { get; set; } 4 public string Name { get; set; } 5 public int Grade { get; set; } 6 public string Nick { get; set; } 7 public string City { get; set; } 8 }
添加一条学生记录到数据表中,有时,只能够获取到部分学生信息,如:不知道学生SharpL的Grade信息,代码如下:
1 Student stu = new Student(); 2 stu.Name = "SL3"; 3 stu.City = "扬州";
操作语句如下:
1 var parameters = new List<SqlParameter>(); 2 3 using (SqlConnection conn = ConnDB.CreateConn()) 4 { 5 conn.Open(); 6 string str = "insert into Stu(Name,City,Grade,Nick) values(@Name,@City,@Grade,@Nick)"; 7 if (stu.Name != null) 8 { 9 parameters.Add(new SqlParameter() { ParameterName = "@Name", Value = stu.Name }); 10 } 11 else 12 { 13 parameters.Add(new SqlParameter() { ParameterName = "@Name", Value = DBNull.Value }); 14 } 15 if (stu.City != null) 16 { 17 parameters.Add(new SqlParameter() { ParameterName = "@City", Value = stu.City }); 18 } 19 else 20 { 21 parameters.Add(new SqlParameter() { ParameterName = "@City", Value = DBNull.Value }); 22 } 23 if (stu.Nick != null) 24 { 25 parameters.Add(new SqlParameter() { ParameterName = "@Nick", Value = stu.Nick }); 26 } 27 else 28 { 29 parameters.Add(new SqlParameter() { ParameterName = "@Nick", Value = DBNull.Value }); 30 } 31 if (stu.Grade != 0) 32 { 33 parameters.Add(new SqlParameter() { ParameterName = "@Grade", Value = stu.Grade }); 34 } 35 else 36 { 37 parameters.Add(new SqlParameter() { ParameterName = "@Grade", Value = DBNull.Value }); 38 } 39 ConnDB.Excute(str, conn, parameters); 40 }
其中的sql语句为:
insert into Stu(Name,City,Grade,Nick) values(@Name,@City,@Grade,@Nick)
在sql语句中,同时存在查询参数Name,City,Grade和Nick,所以需要判断每一个查询参数是否为NUll,然后分别赋值,注意如果这里不判空.
代码如下:
1 parameters.Add(new SqlParameter() { ParameterName = "@Grade", Value = stu.Grade });
当stu.Nick为null时,程序将报错:“参数化查询 需要参数 但未提供该参数 ”。
当stu.Grade不赋予数值时,将取C#整形数据的默认值0,同样不是理想的结果,Nick和Grade均应赋值为null,所以必须判断该字段是否为空。
于是,引入了根据实体的实际数值,动态生成sql语句的方法,Show You the Code:
1 string str = @"insert into Stu(ColumnName) values(ColumnValue)"; 2 if (stu.Name != null) 3 { 4 columnName.Append(",Name"); 5 columnValue.Append(",@Name"); 6 parameters.Add(new SqlParameter() { ParameterName = "@Name", Value = stu.Name }); 7 } 8 if (stu.Nick != null) 9 { 10 columnName.Append(",Nick"); 11 columnValue.Append(",@Nick"); 12 parameters.Add(new SqlParameter() { ParameterName = "@Nick", Value = stu.Nick }); 13 } 14 if (stu.Grade != 0) 15 { 16 columnName.Append(",Grade"); 17 columnValue.Append(",@Grade"); 18 parameters.Add(new SqlParameter() { ParameterName = "@Grade", Value = stu.Grade }); 19 } 20 if (stu.City != null) 21 { 22 columnName.Append(",City"); 23 columnValue.Append(",@City"); 24 parameters.Add(new SqlParameter() { ParameterName = "@City", Value = stu.City }); 25 } 26 str = str.Replace("ColumnName", columnName.ToString().TrimStart(",".ToCharArray())); 27 str = str.Replace("ColumnValue", columnValue.ToString().TrimStart(",".ToCharArray()));
如代码所示,需要判断City等字段是否为null,以及Grade字段是否为0(不合理,有待改进),来决定是否添加查询参数City或者是Grade。
以上,两种方法在字段的个数相当的时候,代码量不相上下,当实体的属性较多时,后一种明显占优。