C# 这是防御代码还是有可能遇到问题?

C# 这是防御代码还是有可能遇到问题?,c#,sql-server-2008-r2,C#,Sql Server 2008 R2,我有下面的代码,它连接到一个db>运行一个存储的proc>,然后继续 我相信db编程很容易出错,所以防御性很重要:以下是防御性的吗?还是可以改进 public int RunStoredProc() { SqlConnection conn = null; SqlCommand dataCommand = null; SqlParameter param = null; int myOutputValue; try { conn = new SqlConnection(Configur

我有下面的代码,它连接到一个db>运行一个存储的proc>,然后继续

我相信db编程很容易出错,所以防御性很重要:以下是防御性的吗?还是可以改进

public int RunStoredProc()
{
SqlConnection conn = null;
SqlCommand dataCommand = null;
SqlParameter param = null;
int myOutputValue;

try
{
    conn = new SqlConnection(ConfigurationManager.ConnectionStrings["IMS"].ConnectionString);                  
    conn.Open();
    dataCommand = conn.CreateCommand();
    dataCommand.CommandType = CommandType.StoredProcedure;
    dataCommand.CommandText = "pr_blahblah";
    dataCommand.CommandTimeout = 200; //seconds
    param = new SqlParameter();
    param = dataCommand.Parameters.Add("@NumRowsReturned", SqlDbType.Int);
    param.Direction = ParameterDirection.Output;
    dataCommand.ExecuteNonQuery();
    myOutputValue = (int)param.Value;

    return myOutputValue;
}
catch (SqlException ex)
{
    MessageBox.Show("Error:" + ex.Number.ToString(), "Error StoredProcedure");
    return 0;
}
finally
{
    if (conn != null)
    {
        conn.Close();
        conn.Dispose();
    }
}
}
代码现在如下所示

我已尝试使用所有人提供的所有帮助,上述代码现在已修改为以下内容,我希望这些内容现在具有足够的防御性:

尝试使用,嗯,使用构造来处理这些事情

using(var conn = new SqlConnection(ConfigurationManager.ConnectionStrings["IMS"].ConnectionString)
{
}
一旦你做到这一点,我认为你将处于正确的防守水平。类似地,尝试对任何必须处理的内容执行相同的操作,如命令

尝试对这些内容使用using构造

using(var conn = new SqlConnection(ConfigurationManager.ConnectionStrings["IMS"].ConnectionString)
{
}

一旦你做到这一点,我认为你将处于正确的防守水平。类似地,尝试对必须处理的任何内容执行相同的操作,如命令If MessageBox.bathror:+ex.Number.ToString,Error stored procedure;是您将如何处理异常,然后您不会记录甚至检索实际的异常详细信息。

如果MessageBox.bathror:+ex.Number.ToString,则错误存储过程;是处理异常的方式,而不是记录甚至检索实际的异常详细信息。

除了manojlds的建议之外,我建议您创建一些可重用的帮助器方法来调用数据库。例如,让自己成为一个读取连接字符串、创建连接并打开连接的方法。不要到处重复基础设施的东西


对于调用存储过程或命令文本,您也可以这样做。

除了manojlds的建议之外,我建议您自己创建一些可重用的助手方法来调用数据库。例如,让自己成为一个读取连接字符串、创建连接并打开连接的方法。不要到处重复基础设施的东西


您可以对调用存储过程或命令文本执行相同的操作。

我注意到的主要内容是数据库访问代码中的MessageBox。我想不出一个场景是有用的。让例外上升吧。别听懂了

作为通用模板:

using(var conn = CreateConnection())
using(var cmd = conn.CreateCommand())
{
    // setup cmd and the parameters
    conn.Open();
    cmd.ExecuteNonQuery();
    // post-process cmd parameters (out/return/etc)
}
注:无闭合,无捕捉;所有的最终结果都由用户来处理。简单得多;更难出错

另一个需要强调的是使用工厂方法来创建连接;不要放:

new SqlConnection(ConfigurationManager.ConnectionStrings["IMS"].ConnectionString)

融入每一种方法;毕竟这可能会改变,而且不需要重复。

我注意到的主要问题是数据库访问代码中有一个MessageBox。我想不出一个场景是有用的。让例外上升吧。别听懂了

作为通用模板:

using(var conn = CreateConnection())
using(var cmd = conn.CreateCommand())
{
    // setup cmd and the parameters
    conn.Open();
    cmd.ExecuteNonQuery();
    // post-process cmd parameters (out/return/etc)
}
注:无闭合,无捕捉;所有的最终结果都由用户来处理。简单得多;更难出错

另一个需要强调的是使用工厂方法来创建连接;不要放:

new SqlConnection(ConfigurationManager.ConnectionStrings["IMS"].ConnectionString)
融入每一种方法;毕竟这可能会改变,这是不必要的重复

无需同时调用.Close和.Dispose 选择using块而不是try finally 处置命令对象 我将删除catch条款。但它不属于这里。 如果你打算到处写这段代码,停下来。至少创建一个小的帮助器类来实现这一点,或者使用一个轻量级的“ORM”类,或者。有关ADO.Net帮助程序类的示例,请参见

无需同时调用.Close和.Dispose 选择using块而不是try finally 处置命令对象 我将删除catch条款。但它不属于这里。
如果你打算到处写这段代码,停下来。至少创建一个小的帮助器类来实现这一点,或者使用一个轻量级的“ORM”类,或者。有关ADO.Net helper类的示例,请参见。

理想情况下,您也应该处理command对象。查找问题,因为我必须创建一个全新的项目;那辆旧的似乎有一个我找不到的毛病。。就像背景中正在发生的事情;即使是在.cs代码文件中,如果我想上下滚动,一切都会延迟,我也会遇到MessageBox.Show的问题;如果用户碰巧离开键盘,那么在用户单击“确定”之前,是否会停止线程?保持连接无限期打开?@ChrisSinclair+1其他人也提到了这一点,我现在正在处理它。实际上,您也应该处理命令对象;那辆旧的似乎有一个我找不到的毛病。。就像背景中正在发生的事情;即使是在.cs代码文件中,如果我想上下滚动,一切都会延迟,我也会遇到MessageBox.Show的问题;如果用户碰巧离开键盘,那么在用户单击“确定”之前,不会停止线程吗?保持连接无限期打开?@ChrisSinclai
r+1其他人也提到了这一点,我现在正在处理它。我还要强调的是,该命令需要在ANKS中进行处理——这也会处理命令对象吗?我假设command对象只能存在于using的范围内,所以也会被收集?@marc Gravell…那么在上面的命令对象中有一个单独的using嵌套吗?@whytheq-您可以在外部的语句中有一个类似的using语句。事实上,我还想强调的是,该命令需要被处理掉这也处理命令对象吗?我假设命令对象只能存在于using的范围内,所以也会被收集?@marc Gravell…所以在上面的命令对象中有一个单独的using嵌套?@whytheq-你可以在外部的using语句中有一个类似的using语句。很好的一个帮助…作为一个新手,我不确定你说的另一件事是什么意思强调的是使用工厂方法创建连接-我该怎么做?好的-那么你的这一行var conn=CreateConnection就是你用工厂方法描述的吗?@whytheq通过编写一个方法,比如CreateConnection,并从当前执行新SqlConnection的各个位置调用它…@whytheq如果用CreateConnection之类的方法包装它,那么是的,它将类似于公共SqlConnectionCreateConnection{SqlConnectionConn=new SqlConnectionConfiguration Manager.ConnectionString[IMS].ConnectionString;return conn;}很好的帮助…作为一个新手,我不确定你所说的另一件事是什么意思,要强调的是使用工厂方法来创建连接-我该怎么做?好的-那么你的这行var conn=CreateConnection就是你所描述的工厂方法吗?@whytheq通过编写一个方法,比如CreateConnection,并从当前执行新SqlConnection的各个位置调用它…@whytheq如果您将其包装为CreateConnection之类的方法,那么是的,它将类似于公共SQLConnectionCreateConnection{SqlConnection conn=new SQLConnectionConfiguration Manager.ConnectionString[IMS].ConnectionString;return conn;}+1感谢;我将添加我对正确代码的尝试-使用我认为是OP+1中的帮助器方法,谢谢;我将添加我对正确代码的尝试——我认为是OP中的一个助手方法