2016-05-07 14 views
0

私のリポジトリには、2つのテーブルを更新するこの非同期メソッドがあります。テーブルは異なるスキーマにあり、したがって2つのコンテキストになります。コンテキストは、このリポジトリ内のクラス変数です。このメソッドは、Angularクライアントアプリケーションによって呼び出されるwebapiから呼び出されます。私は両方の挿入が成功するか両方が失敗することを保証する必要があります。複製されたレコードをどちらのコンテキストでも挿入しようとすると、重複していないレコードが渡されても、サーバーは常にそのレコードを覚えます。サーバーは、ホスティングサーバーが再起動されるまで失敗を返します。誰もトランザクションスコープでこれを処理する方法を知っていますか?リポジトリで非同期メソッド内でトランザクションスコープを使用する方法

public class RepositoryAsync: IRepositoryAsync { 
 
    //CareMgmtTool schema context 
 
    private CareMgmtToolContext cmtCtx = new CareMgmtToolContext(); 
 

 
    //App schema context 
 
    private AppContext appCtx = new AppContext(); 
 

 
    //UserProfile schema 
 
    private UserProfileContext userProfileCtx = new UserProfileContext(); 
 

 
    public async Task <int> PostUserFSR(int userId, int fsrId) { 
 
    //poor man's transaction scope 
 
    bool operation1Success, operation2Success = false; 
 
    UserProfile_UserFacilityServiceRole vm1 = new UserProfile_UserFacilityServiceRole(); 
 
    vm1.UserId = userId; 
 
    vm1.FacilityServiceRoleId = fsrId; 
 
    UserProfile_UserFacilityServiceRole ufsr_UserProfileSchema = userProfileCtx 
 
     .UserProfile_UserFacilityServiceRole.Add(vm1); 
 
    operation1Success = true; 
 

 
    App_SUserFacilityServiceRole vm2 = new App_SUserFacilityServiceRole(); 
 
    vm2.UserId = userId; 
 
    vm2.FacilityServiceRoleId = fsrId; 
 
    App_SUserFacilityServiceRole ufsr_appSchema = appCtx.App_SUserFacilityServiceRole.Add(vm2); 
 
    operation2Success = true; 
 

 
    if (operation1Success && operation2Success) { 
 
     await userProfileCtx.SaveChangesAsync(); 
 
     await appCtx.SaveChangesAsync(); 
 
    } 
 

 
    return ufsr_UserProfileSchema.UserFacilityServiceRoleId; //record key 
 
    } 
 

 
}

答えて

0

私は https://msdn.microsoft.com/en-us/data/dn456843.aspxの文書に続き、ここではトランザクションを使用して3つのシナリオを示します。私の場合は、同じコンテキストでトランザクションを開始する最初のシナリオを使用しました。 3つのシナリオを持つサンプルではSQLコマンドを使用していますが、SQLコマンドやTransactionScopeを使用せずに、EF LINQ add()とremove()を使用するだけです。 「新しいDatabase.BeginTransaction()およびDatabase.UseTransaction()APIを使用すると、TransactiionScopeのアプローチはほとんどのユーザーにとってもはや必要ではありません」という記事の引用です。

0

TransactionScopeAsyncFlowOption有効とのTransactionScopeとロジックをラップしてください。ここに参考として良いsourceがあります。以下のコードを参考にしてください(このコードはテストされていません)。

public async Task <int> PostUserFSR(int userId, int fsrId) 
    { 
     using (var scope = 
      new TransactionScope(TransactionScopeAsyncFlowOption.Enabled)) 
     { 
      try{ 
      UserProfile_UserFacilityServiceRole vm1 = new UserProfile_UserFacilityServiceRole(); 
      vm1.UserId = userId; 
      vm1.FacilityServiceRoleId = fsrId; 
      UserProfile_UserFacilityServiceRole ufsr_UserProfileSchema = userProfileCtx 
       .UserProfile_UserFacilityServiceRole.Add(vm1); 

      App_SUserFacilityServiceRole vm2 = new App_SUserFacilityServiceRole(); 
      vm2.UserId = userId; 
      vm2.FacilityServiceRoleId = fsrId; 
      App_SUserFacilityServiceRole ufsr_appSchema = appCtx.App_SUserFacilityServiceRole.Add(vm2); 
       await userProfileCtx.SaveChangesAsync(); 
       await appCtx.SaveChangesAsync(); 
     scope.Complete(); 
      return ufsr_UserProfileSchema.UserFacilityServiceRoleId; //record key 
       } 
     } 
     catche(Exception ex) 
     { 
      return 0; 
     } 
    } 

ありがとう、 Soma。

関連する問題