【问题标题】:Usage of nested using in C# and SQL Server在 C# 和 SQL Server 中嵌套 using 的用法
【发布时间】:2010-02-09 15:12:53
【问题描述】:

这个话题是Is there a reason to check for null inside multiple using clausule in c#?的延续

我注意到 resharper 让我可以在不打开任何左/右括号的情况下定义使用,就像下面的方法一样(但是如果括号不存在,我以后就不能使用定义的变量了,除了那个完全在下面定义 using):

public static string sqlGetDatabaseRows() {
        string varRows = "";
        const string preparedCommand = @"
                    SELECT SUM(row_count) AS 'Rows'
                    FROM sys.dm_db_partition_stats
                    WHERE index_id IN (0,1)
                    AND OBJECTPROPERTY([object_id], 'IsMsShipped') = 0;";
        using (var varConnection = Locale.sqlConnectOneTime(Locale.sqlDataConnectionDetailsDZP))
        using (var sqlQuery = new SqlCommand(preparedCommand, varConnection))
        using (var sqlQueryResult = sqlQuery.ExecuteReader())
            if (sqlQueryResult != null) {
                while (sqlQueryResult.Read()) {
                    varRows = sqlQueryResult["Rows"].ToString();
                }
                sqlQueryResult.Close();
            }
        return varRows;
    }

好吃吗?还是应该这样使用?

public static string sqlGetDatabaseRows() {
        string varRows = "";
        const string preparedCommand = @"
                    SELECT SUM(row_count) AS 'Rows'
                    FROM sys.dm_db_partition_stats
                    WHERE index_id IN (0,1)
                    AND OBJECTPROPERTY([object_id], 'IsMsShipped') = 0;";
        using (var varConnection = Locale.sqlConnectOneTime(Locale.sqlDataConnectionDetailsDZP)) {
            using (var sqlQuery = new SqlCommand(preparedCommand, varConnection))
            using (var sqlQueryResult = sqlQuery.ExecuteReader())
                if (sqlQueryResult != null) {
                    while (sqlQueryResult.Read()) {
                        varRows = sqlQueryResult["Rows"].ToString();
                    }
                    sqlQueryResult.Close();
                }
            varConnection.Close();
        }
        return varRows;
    }

sqlConnectOneTime 如下所示:

    public static SqlConnection sqlConnectOneTime(string varSqlConnectionDetails) {
        SqlConnection sqlConnection = new SqlConnection(varSqlConnectionDetails);
        sqlConnect(sqlConnection);
        if (sqlConnection.State == ConnectionState.Open) {
            return sqlConnection;
        }
        return null;
    }

我的问题是:

  1. 我是否应该使用 varConnection.Close() 和 sqlQueryResult.Close() 来关闭 varConnection;到底? (但这会强制使用括号)或者在使用完成后连接会自行关闭。

  2. 我是否应该为 varConnection 检查 NULL,因为它可能会返回 null(另一方面,resharper 不会在这里抱怨)。

  3. 有没有更好的方法可以用来定义 sqlConnectOneTime ?就像当连接无法打开时它应该返回 ConnectionState.Closed 而不是 null?

另外,我在每次执行新查询/更新/插入时都会打开新连接,因为我使用的是线程,这是我当时能想到的最聪明的想法。随意提出更好的建议:-)

我之所以问这一切,是因为我想更好地了解整个过程并停止犯愚蠢的错误,所以对我温柔一点。

疯子

编辑:如果 varConnection.Close() 和 sqlQueryResult.Close() 在使用 using 时是必要的,则修改问题。

【问题讨论】:

    标签: c# sql sql-server-2005 sql-server-2008 multithreading


    【解决方案1】:
    1. Close() 由 Dispose() 方法调用,因此只要您正确使用“使用”,就不需要显式调用 Close()。
    2. 如果可能返回 NULL,您应该检查它。我建议如果您控制获取 sql 连接的代码,您强烈考虑抛出异常而不是返回 NULL。否则其他开发人员可能会遇到同样的问题。在我看来,未能打开所需的 SQL 连接似乎是一个有效的例外情况。如有必要,您始终可以在开发人员想要避免异常处理时添加 TryConnectOneTime。

    另外,另一种风格说明 - 我建议正确地支撑您的 using 语句,以防添加了多余的额​​外行并发生意外错误。就风格而言,当我将多个语句放在一起时,我通常不倾向于使用语句缩进,但这完全取决于个人喜好。

    【讨论】:

    • 问题是我是唯一一个创建这个应用程序的人,所以没有人会调用它:-) 抛出异常也不是一个好主意,因为它会使用户感到困惑。我想最好的选择是保持安静,这样如果查询没有被执行,用户就不会得到任何信息,所以他/她只是重试。最终我想我可以添加一些 MessageBox 说如果他/她想再试一次就无法建立连接?你认为这是最好的方法吗?
    • 我当然不认为您应该将异常直接暴露给用户。但是,这不应该是连接调用的关注点。它的签名相当清楚——它负责创建连接。如果它不能执行这个任务,那么它抛出一个异常是合理的(并且调用代码会捕获这个并适当地处理它)。通过返回 null,您将返回一个意外的值,更糟糕的是,没有提供有关此连接失败原因的任何信息。通过抛出异常,您可以解决这两个问题。
    【解决方案2】:

    像第一个例子一样使用它是安全的。 using 关闭阅读器、命令和连接对象,甚至检查 null 值(所以如果 varConnectionnull,你不会得到 NullReferenceException

    【讨论】:

    • 如果这些变量中的任何一个为空,它会做什么?如果 varConnection 为 null,它将返回并且不执行第一次、第二次使用中的内容。
    • 我所说的空检查是指在调用 Dispose 之前,它会检查变量是否为空。因此,在将varConnection 传递给其他方法之前,您仍然必须检查它是否为空。但是,我建议不要从 sqlConnectOneTime 方法返回 null 值,而是抛出异常。
    猜你喜欢
    • 2010-11-22
    • 1970-01-01
    • 1970-01-01
    • 2017-11-02
    • 2021-05-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多