如何根据实体动态生成sql语句

该文章同时解决了,如何向数据库中添加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     }
View Code

  添加一条学生记录到数据表中,有时,只能够获取到部分学生信息,如:不知道学生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             }
View Code

其中的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。

  以上,两种方法在字段的个数相当的时候,代码量不相上下,当实体的属性较多时,后一种明显占优。

  

原文地址:https://www.cnblogs.com/SharpL/p/4640834.html