SqlParameter一个容易出错的问题(@2.0)

本文解决了一个关于SqlParameter在多次调用中出现重复导致的系统错误问题。通过调整代码逻辑,每次循环内部重新创建SqlParameter实例,避免了参数集合中SqlParameter重复的情况。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

近日在做培训系统的时候遇到了一个一下的问题,主要涉及的问题如下:

        public Models.Timu ListTimu(IList<Models.TimuDesc> TimuDescs, bool IsKaoshi)
        
{

            Models.Timu rtnValue 
= new Models.Timu();
            SqlParameter[] param 
= new SqlParameter("@spoint"0), new SqlParameter("@tid", Guid.Empty) };
            SqlConnection cn 
= new SqlConnection(CNSTRING);
            cn.Open();
            
foreach (Models.TimuDesc td in TimuDescs)
            
{
                
string SQL = string.Format(SQL_SelectTimuNotKaoshiFormat, td.Point1);
                
for (int i = 1; i <= 3; i++)
                
{
                    param[
0].Value = i;
                    param[
1].Value = td.Guid;
                    DBUtility.SQLHelper.Fill(rtnValue._Timu, cn, CommandType.Text, SQL, param);
                }

            }

            cn.Close();
            
return rtnValue;
        }




        
public static void Fill(DataTable TypedDataSetsTable, SqlConnection conn, CommandType cmdType, string cmdText, params SqlParameter[] commandParameters)
        
{
            SqlConnection conection 
= conn;
            SqlCommand cmd 
= new SqlCommand();
            PrepareCommand(cmd, conn, 
null, cmdType, cmdText, commandParameters);
            SqlDataAdapter ada 
= new SqlDataAdapter(cmd);
            ada.Fill(TypedDataSetsTable);
        }




        
private static void PrepareCommand(SqlCommand cmd, SqlConnection conn, SqlTransaction trans, CommandType cmdType, string cmdText, SqlParameter[] cmdParms)
        
{

            
if (conn.State != ConnectionState.Open)
                conn.Open();

            cmd.Connection 
= conn;
            cmd.CommandText 
= cmdText;

            
if (trans != null)
                cmd.Transaction 
= trans;

            cmd.CommandType 
= cmdType;

            
if (cmdParms != null)
            
{
                
foreach (SqlParameter parm in cmdParms)
                    cmd.Parameters.Add(parm);
            }

        }

明眼人一看就知道,最后一段是SqlHelper里的一个方法,而第二段代码是我仿造SqlHelper扩展的代码,从这里,当执行的时候,会报以下错误

System.ArgumentException: 另一个 SqlParameterCollection 中已包含 SqlParameter。

SqlParameter[] param = ...new SqlParameter("@spoint"0), new SqlParameter("@tid", Guid.Empty) };
            SqlConnection cn 
= new SqlConnection(CNSTRING);
            cn.Open();
            
foreach (Models.TimuDesc td in TimuDescs)
            ...
{
                
string SQL = string.Format(SQL_SelectTimuNotKaoshiFormat, td.Point1);
                
for (int i = 1; i <= 3; i++)
                ...
{
                    param[
0].Value = i;
                    param[
1].Value = td.Guid;
                    DBUtility.SQLHelper.Fill(rtnValue._Timu, cn, CommandType.Text, SQL, param);
                }

            }

            cn.Close();

这里是唯一存入参数的地方肯定这里就问题所在了,我之所以这样写法是因为希望节省一点 SqlParameter 的new时间,而在Fill 方法中SqlCommand的对象是被new出来的,所以每次调用new方法Fill 方法 cmd (SqlCommand) 都是新的唯一能做到多次调用都能被记录住的“公用地方”就是SqlConnection对象了。 但是没有理由我没次调用Fill 都要Open和Close Connection 一次吧,于是我想试一下把这些都 new 一下看看。

于是将代码改成如下:
        public Models.Timu ListTimu(IList<Models.TimuDesc> TimuDescs, bool IsKaoshi)
        
{

            Models.Timu rtnValue 
= new Models.Timu();
            
            SqlConnection cn 
= new SqlConnection(CNSTRING);
            cn.Open();
            
foreach (Models.TimuDesc td in TimuDescs)
            
{
                
string SQL = string.Format(SQL_SelectTimuNotKaoshiFormat, td.Point1);
                
for (int i = 1; i <= 3; i++)
                
{
                    SqlParameter[] param
                        
= new SqlParameter("@spoint", i), new SqlParameter("@tid", td.Guid) };
                    DBUtility.SQLHelper.Fill(rtnValue._Timu, cn, CommandType.Text, SQL, param);
                }

            }

            cn.Close();
            
return rtnValue;
        }

运行,问题解决
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值