0

コードベースには、2つの異なる方法でステートメントを使用して使用したさまざまなデータアクセスコードが含まれていることがわかりました。もしあればどちらがより良い方法であり、これらの2つの方法は異なりますか?usingステートメントでSqlConnectionとSqlCommandをインスタンス化しないことから発生する可能性のある問題はありますか?明らかな不整合の問題は無視してください。

方法1:

public int SampleScalar(string query, CommandType queryType, SqlParameter[] parameters)
    {
        int returnValue = 0;
        SqlConnection objConn = new SqlConnection(ConnString);
        SqlCommand objCmd = new SqlCommand(query, objConn);
        objCmd.CommandType = queryType;

        if (parameters.Length > 0)
            objCmd.Parameters.AddRange(parameters);

        using (objConn)
        {
            using (objCmd)
            {
                objConn.Open();
                try
                {
                    returnValue = (int)objCmd.ExecuteScalar();
                }
                catch (SqlException e)
                {
                    Errors.handleSqlException(e, objCmd);
                    throw;
                }
            }
        }
        return returnValue;
    }

方法2:

public int SampleScalar2(string query, CommandType queryType, SqlParameter[] parameters)
    {
        int returnValue = 0;
        using (SqlConnection objConn = new SqlConnection(ConnString))
        {
            using (SqlCommand objCmd = new SqlCommand(query, objConn))
            {
                objConn.Open();
                objCmd.CommandType = queryType;

                if (parameters.Length > 0)
                    objCmd.Parameters.AddRange(parameters);
                try
                {
                    returnValue = (int)objCmd.ExecuteScalar();
                }
                catch (SqlException e)
                {
                    Errors.handleSqlException(e, objCmd);
                    throw;
                }
            }
        }
        return returnValue;
    }
4

5 に答える 5

5

最初のスニペットでは、オブジェクトの作成後、使用開始前に例外が発生した場合、IDisposableオブジェクトは適切に破棄されません。2番目の実装では、リソースが解放されない可能性のあるギャップはありません。

最初のアプローチで発生する可能性のある別の問題は、オブジェクトが破棄された後に使用できることです。これは、うまく終了しない可能性があります。

例外が発生しないことを確認している可能性がありますが、そうではない可能性があります。一般に、私は自分自身(または他の誰か)がその保護されていないスペースで間違いを犯すことは決してないという理由だけで、最初の方法を使用することは決してありません。他に何もないとしても、何も問題が発生しないことを確認するために、非常に注意深く調べるために時間と労力を費やす必要があります。安全性の低い方法を使用しても、実際には何も得られません。

于 2012-08-28T17:20:28.770 に答える
1

2番目の方が良いです。http://msdn.microsoft.com/en-us/library/yh598w02.aspx最後のコメントをお読みください。

最初のオブジェクトは、廃棄された後もスコープ内にとどまります。その場合、それを使用することは良い習慣ではありません。

于 2012-08-28T17:23:14.100 に答える
1

私はいつも2番目の方法を使います。特定のブロックの最後にどのオブジェクトが破棄されているかを読み、理解する方が簡単です。また、廃棄されたオブジェクトを使用できなくなります。

于 2012-08-28T17:19:29.700 に答える
1

を使用しない場合は、オブジェクトを管理せずに廃棄せず、GCは廃棄しません

GCは管理対象のオブジェクトのみを破棄し、SQL接続は管理されないため、最後にusedisposeを使用して破棄する必要があります

于 2012-08-28T17:19:48.140 に答える
1

MSDNによる

リソースオブジェクトをインスタンス化してから、変数をusingステートメントに渡すことができますが、これはベストプラクティスではありません。この場合、オブジェクトは、管理されていないリソースにアクセスできなくなったとしても、制御がusingブロックを離れた後もスコープ内にとどまります。つまり、完全に初期化されなくなります。usingブロックの外部でオブジェクトを使用しようとすると、例外がスローされるリスクがあります。このため、通常、usingステートメントでオブジェクトをインスタンス化し、そのスコープをusingブロックに制限することをお勧めします。

于 2012-08-28T17:21:21.007 に答える