2

私はグーグルで検索してきましたが、同様の質問を見つけましたが、正確にはそうではありません。データ処理呼び出しの後、最後にエラーを発生させるSQL Server 2005ストアドプロシージャがあります。

    Create Procedure webzTest(
      @nClaPais Int
    )
    As
    Begin 

        Select * From zPais Where ClaPais = @nClaPais
        Raiserror('TEST ERROR!!!', 16, -1)  
    End

クライアント側では、Entity Framework (Visual Studio 2012) が例外をキャッチしようとしますが、無視されます。

    public static void webzTestTransaction()
    {
        using (var ctx = new MyWebEntities())
        {
            using (var trx = MyTransactionScope.newTransactionScope())
            {
                var connection = ((IObjectContextAdapter)ctx).ObjectContext.Connection;
                connection.Open();  // Open connection explicitly to avoid EF closing and reopening which invokes DTC
                try
                {
                    ctx.webzTest(1).ToList();
                    ctx.webzTest(2).ToList();
                    trx.Complete();
                }
                catch (Exception ex)
                {
                    logger.Error(ex);
                    throw ex;
                }
                finally
                {
                    connection.Close();
                }
            }
        }
    }

発生したエラーは無視されます。Raiserror() ステートメントを Select の前に置くと、EF コードによって例外がキャッチされますが、上記のコードでも同じ動作が期待されます。

ADO.NET を使用した同様の例を追加しましょう。この場合、例外は期待どおりにキャッチされます。

        SqlConnection conn = new SqlConnection(connectionString);
        conn.Open();

        SqlTransaction trx = null;
        try
        {
            trx = conn.BeginTransaction(IsolationLevel.ReadUncommitted);

            SqlCommand cmd = new SqlCommand();
            cmd.CommandType = System.Data.CommandType.StoredProcedure;
            cmd.Connection = conn;
            cmd.CommandText = "webzTest";
            cmd.Transaction = trx;

            var parClaPais = new SqlParameter("@nClaPais", SqlDbType.Int);
            cmd.Parameters.Add(parClaPais);

            parClaPais.Value = 1;
            SqlDataReader result1 = cmd.ExecuteReader();

            parClaPais.Value = 2;
            SqlDataReader result2 = cmd.ExecuteReader();
            trx.Commit();
            trx = null;
        }
        catch (Exception ex)
        {
            if (trx != null)
                trx.Rollback();

            throw ex;
        }
        finally
        {
            conn.Close();
        }

次に: EF の何が問題なのですか? またはこの場合に従うべきルールはどれですか?

前もって感謝します

4

0 に答える 0