2011-07-20 11 views
0

私は次のことを実施するための最良の方法や練習であると思いまして:EF取引C#のMySQLのコネクタ

私は次のように定義があるEditUserと呼ばれる方法があります:あなたは気づくことのよう

public void EditUser(user user, Roles role) 
    { 
     using (TestEntities entities = new TestEntities()) 
     { 
      entities.Connection.Open(); 
      using (DbTransaction trans = entities.Connection.BeginTransaction()) 
      { 
       try 
       { 
        var tmpUser = entities.users.Where(fields => fields.UserId == user.UserId).FirstOrDefault(); 

        RoleManagement rm = new RoleManagement(); 
        string oldRole = tmpUser.roles.FirstOrDefault().Name; 
        string newRole = rm.GetRoleName(role); 

        if (oldRole == newRole) 
        { 
         entities.users.ApplyCurrentValues(user); 
        } 
        else 
        { 
         rm.UnbindRoles(tmpUser.UserId, entities.Connection); 
         this.DeleteUser(tmpUser.UserId, entities.Connection); 
         this.Register(user, role, entities.Connection); 
        } 

        entities.SaveChanges(); 
        trans.Commit(); 
       } 
       catch (Exception ex) 
       { 
        trans.Rollback(); 
        throw ex; 
       } 
      } 
     } 
    } 

を私は、UnbindRoles、DeleteUser、RegisterUserといういくつかのメソッドを呼び出しています。何かが失敗した場合は、ロールバックする必要があるため、すべて同じトランザクション(EditUserが実行している同じトランザクション)で実行する必要があります。

私の問題は主にここにあります... RegisterUserメソッドは、ユーザーを追加して新しいユーザーに役割を割り当てるため、新しいトランザクションも開始します。

誰もがこれを実装する最良の方法を記述できますか?私はのTransactionScopeブロックを使用してみましたが、私は私ので、ミディアム・トラストの下のTransactionScopeを使用した場合のMySQL .NETコネクタプロバイダがバグを持っていることを確認ミディアム・トラスト環境

EDIT

でこのアプリケーションを実行していますので、それが失敗しましたMS SQL Serverデータベースを使用して同じシナリオをテストしましたが、問題なく動作します。

+0

に対処することができます!スロー・エックス; !!! スタックタクシーを本当に失いたくない場合は、投げてください。 – BennyM

+0

そのスローは呼び出し元によってキャッチされ、再度スローされます。これにより、Application_ErrorイベントのGlobal.asaxがエラーの汎用処理を行います – Ryan

+0

スローの違いを知っていることを確認します。 exを投げる; – BennyM

答えて

1

私が正しく理解しているのは、DeleteUserとRegisterUserの呼び出しが新しいトランザクションを開始しているため、現在のトランザクションに参加する必要があるということです。この問題を解決するために

いくつかの方法:

A)あなたはすでに利用可能な1が存在しない場合、彼らは一つだけを作成する必要があると言うことができるのTransactionScopeを作成する場合。

B)プライベートメソッドを導入すると、ロジックを含むInnerEditとInnerRegisterがありますが、公開されている編集と登録メソッドに残っているトランザクションは開いたり閉じたりしないようにしましょう。これらの「内部」メソッドは、公共のインフラストラクチャを含む間に再利用することができます。 ああのNOE:あなたはアスペクト指向プログラミングのための第二のアプローチグーグルをつもりなら、それは、これらの「横断的関心事」別のトピックで

public void EditUser(user user, Roles role) 
{ 
    using (TestEntities entities = new TestEntities()) 
    { 
     entities.Connection.Open(); 
     using (DbTransaction trans = entities.Connection.BeginTransaction()) 
     { 
      InnerEditUser(entities, trans); 
      InnerThat(entities, trans); 
      InnerThis(entities,trans); 
      entities.SaveChanges(); 
      trans.Commit(); 
     } 
    } 
} 

TransactionScope options MSDN link

+0

私はuserFromDb EntityObjectの下でChangeRoleメソッドを取得した場所がわかりません。説明してください。 – Ryan

+0

あなたが作成したユーザーとロールのクラスですか?それから私は、手元の問題に合わせて機能を追加します。 – BennyM

+0

しかし、問題は、各メソッドで、(EditUserまたはRegisterUserによって呼び出されることなく)ChangeRoleメソッドまたはAddUserメソッドを手動で呼び出す必要があることがあるので、変更(呼び出しエンティティ.SaveChanges())を保存しているということです。何が起こったのかに応じてコミットまたはロールバックできるトランザクションを持つ – Ryan

0

登録は既存のトランザクションをチェックし、存在しない場合にのみ作成できますか?これは、同様の状況で入れ子にされたTransactionScopesが行うことです。

+0

はい、これはオプションですが、最初はこのオプションが「パッチワーク」のようなものであると考えていました – Ryan

+0

これは基本的にはTransactionScopeの機能です - それが存在する場合は周囲トランザクションで登録し、そうでなければ新しいトランザクションを作成します。 TransactionScopeを使用することができないので、あなた自身がこれをやっているだけです。方法でそれをうまくまとめれば、それは私には正当だと思われます。 – jlew

関連する問題