近日在做培训系统的时候遇到了一个一下的问题,主要涉及的问题如下:
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;
}
运行,问题解决
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;
}运行,问题解决
本文解决了一个关于SqlParameter在多次调用中出现重复导致的系统错误问题。通过调整代码逻辑,每次循环内部重新创建SqlParameter实例,避免了参数集合中SqlParameter重复的情况。
SqlParameter[] param
6900

被折叠的 条评论
为什么被折叠?



