我为SqlCommand编写了一个扩展方法来执行一批命令,我称之为ExecuteBatchNonQuery。这很好用。我已经更改为返回消息输出,为此我必须创建一个从InfoMessage调用的方法。它附加到一个我不得不制作静态的字符串构建器。我担心这个stringbuilder不是线程安全的。我必须使用静态,有什么方法可以让它保持线程安全,还是有替代方法?
internal static class SqlCommandHelper
{
private static readonly StringBuilder StringBuilder = new StringBuilder();
internal static string ExecuteBatchNonQuery(this SqlCommand cmd, string sql)
{
SqlConnection conn = cmd.Connection;
conn.Open();
conn.InfoMessage += MyConnectionInfoMessage;
string sqlBatch = string.Empty;
sql += "\nGO"; // make sure last batch is executed.
StringBuilder.Clear();
try
{
foreach (string line in sql.Split(new string[2] { "\n", "\r" }, StringSplitOptions.RemoveEmptyEntries))
{
if (line.ToUpperInvariant().Trim() == "GO")
{
cmd.CommandText = sqlBatch;
cmd.ExecuteNonQuery();
sqlBatch = string.Empty;
}
else
{
sqlBatch += line + "\n";
}
}
}
finally
{
conn.Close();
}
return StringBuilder.ToString();
}
private static void MyConnectionInfoMessage(object sender, SqlInfoMessageEventArgs e)
{
StringBuilder.AppendLine(e.Message);
}
}
答案 0 :(得分:6)
您的StringBuilder应该是一个局部变量。您可以使用Lambda表达式来实现此目的:
internal static class SqlCommandHelper
{
internal static string ExecuteBatchNonQuery(this SqlCommand cmd, string sql)
{
var sb = new StringBuilder();
SqlConnection conn = cmd.Connection;
conn.Open();
conn.InfoMessage += (sender, e) => { sb.AppendLine(e.Message); };
string sqlBatch = string.Empty;
sql += "\nGO"; // make sure last batch is executed.
sb.Clear();
try
{
foreach (string line in sql.Split(new string[2] { "\n", "\r" }, StringSplitOptions.RemoveEmptyEntries))
{
if (line.ToUpperInvariant().Trim() == "GO")
{
cmd.CommandText = sqlBatch;
cmd.ExecuteNonQuery();
sqlBatch = string.Empty;
}
else
{
sqlBatch += line + "\n";
}
}
}
finally
{
conn.Close();
}
return sb.ToString();
}
}