


















private static SqlCommand BuilderCommand(SqlConnection conn, string sql, int cmdType, SqlTransaction trans, params SqlParameter[] paras) { //如果连接为空,抛出连接对象不能为空的异常 if (conn == null) throw new ArgumentNullException("连接对象不能为空!"); //创建SqlCommand对象用于填装需要执行的sql语句或者存储过程名 SqlCommand command = new SqlCommand(sql, conn); //如果参数cmdType=2,则要执行的是存储过程 if (cmdType == 2) command.CommandType = CommandType.StoredProcedure; //如果连接状态为连接状态关闭 if (conn.State == ConnectionState.Closed) //则打开conn执行用SqlCommand执行sql语句或者存储过程 conn.Open(); if (trans != null) command.Transaction = trans; if (paras != null && paras.Length > 0) { command.Parameters.Clear(); command.Parameters.AddRange(paras); } return command; }逐句解释下 思考中... 我们逐句解释这个方法的每一部分:方法签名:private staticSqlCommand BuilderCommand(SqlConnection conn,string sql,int cmdType, SqlTransaction trans,params SqlParameter[] paras) 这是一个私有静态方法,返回一个SqlCommand对象。它接受以下参数:conn:SqlConnection对象,表示数据库连接。sql:字符串,表示要执行的SQL语句或存储过程名。cmdType:整数,用于指示命令类型(这里2表示存储过程,其他情况视为文本)。trans:SqlTransaction对象,表示事务,可以为null。paras:可变参数的SqlParameter数组,表示命令的参数。逐句解释: if (conn == null) throw newArgumentNullException("连接对象不能为空!"); 检查传入的数据库连接对象是否为空,如果为空则抛出异常。 SqlCommand command= new SqlCommand(sql,conn);使用给定的sql字符串和连接对象创建一个新的SqlCommand对象。3. if(cmdType== 2) command.CommandType =CommandType.StoredProcedure;如果cmdType等于2,则将命令类型设置为存储过程。注意:这里没有处理其他类型(比如1可能表示文本,但代码中没有体现),所以默认是文本。4.if (conn.State == ConnectionState.Closed) conn.Open();检查连接状态,如果连接是关闭的,则打开连接。5.if (trans!= null)command.Transaction = trans;如果传入了事务对象,则将其分配给命令对象。6.if (paras !=null && paras.Length >0){command.Parameters.Clear();command.Parameters.AddRange(paras);} 检查参数数组是否不为空且长度大于0,如果是,则先清除命令对象现有的参数(虽然新建的命令对象参数集合为空,但这里为了安全),然后添加传入的参数数组。7.return command;返回构建好的SqlCommand对象。注意:这个方法有几个潜在问题:a.命令类型只判断了2,其他情况都是默认的文本。如果cmdType是其他值(比如1表示文本,2表示存储过程)那么这里没有处理,但通常我们使用枚举来更清晰地表示。b.连接状态为关闭时,方法会打开连接。但调用者需要注意,这个连接在方法内被打开,但并没有在方法内关闭。调用者需要负责关闭连接。c. 参数处理中,先Clear再AddRange,对于新建的命令对象,Clear可能多余,但如果是重用命令对象则有必要。但这里每次都是新建命令对象,所以Clear可以省略。 通常,我们建议使用枚举来替代数字2,以提高代码可读性。例如:public enum CommandTypeEnum{ Text =1,StoredProcedure= 2}然后方法参数改为CommandTypeEnumcmdType,并在判断时使用cmdType == CommandTypeEnum.StoredProcedure。另外,打开连接的操作也可以考虑由调用者负责,或者使用using语句确保连接关闭。但这里由于返回的SqlCommand对象需要连接打开才能执行,所以打开连接是必要的,但调用者需要管理连接的关闭。由于方法是私有的,所以只要在类的内部使用得当,问题不大。 我来逐句解释这个 BuilderCommand方法: 方法签名 csharp 复制 private static SqlCommand BuilderCommand(SqlConnection conn, string sql, int cmdType, SqlTransaction trans, params SqlParameter[] paras) private:私有方法,只能在当前类内部使用 static:静态方法,不需要创建类实例即可调用 返回类型:SqlCommand- 构建好的数据库命令对象 参数: SqlConnection conn:数据库连接对象 string sql:SQL语句或存储过程名 int cmdType:命令类型(1=文本,2=存储过程) SqlTransaction trans:事务对象(可为null) params SqlParameter[] paras:SQL参数数组(可变参数) 逐句解释 1. 连接对象校验 csharp 复制 if (conn == null) throw new ArgumentNullException("连接对象不能为空!"); 作用:验证传入的连接对象不为空 原理:如果连接为null,直接抛出异常,防止后续操作导致运行时错误 2. 创建命令对象 csharp 复制 SqlCommand command = new SqlCommand(sql, conn); 作用:创建SQL命令对象 参数: sql:要执行的SQL语句或存储过程名 conn:关联的数据库连接 3. 设置命令类型 csharp 复制 if (cmdType == 2) command.CommandType = CommandType.StoredProcedure; 作用:判断是否执行存储过程 逻辑: 如果 cmdType == 2,设置为存储过程模式 默认是文本模式(CommandType.Text),执行普通SQL语句 注:这个设计不直观,建议用枚举代替魔法数字 4. 打开数据库连接 csharp 复制 if (conn.State == ConnectionState.Closed) conn.Open(); 作用:确保连接已打开 状态检查: ConnectionState.Closed:连接关闭 如果关闭,则打开连接 风险:这里打开连接,但方法内不关闭,需要调用者管理连接生命周期 5. 关联事务 csharp 复制 if (trans != null) command.Transaction = trans; 作用:为命令添加事务支持 场景:如果传入事务对象,让命令在该事务中执行,保证操作的原子性 6. 添加SQL参数 csharp 复制 if (paras != null && paras.Length > 0) { command.Parameters.Clear(); command.Parameters.AddRange(paras); } 作用:为SQL命令绑定参数 步骤: 清除现有参数(安全性考虑) 批量添加所有参数 好处:防止SQL注入,提高性能 7. 返回构建好的命令 csharp 复制 return command; 作用:返回完全配置好的SqlCommand对象,可以直接执行 方法总结 这是一个命令构建器方法,用于: 封装命令创建逻辑:简化调用者的代码 确保连接状态:自动打开连接 支持事务:可选的分布式事务支持 参数安全绑定:防止SQL注入 潜在改进点 csharp 复制 // 建议:使用枚举代替魔法数字 public enum CommandType { Text = 1, StoredProcedure = 2 } // 建议:改为泛型方法或使用接口 private static IDbCommand BuildCommand(IDbConnection conn, ...) 这个方法是典型的数据库访问层辅助方法,体现了封装和单一职责原则。
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。