2017-09-30 15 views
0

アーティクルhttps://www.codeproject.com/Articles/1080517/Aspect-Oriented-Programming-using-Interceptors-witの著者は、 "ASPNETボイラープレート"フレームワークでインターセプタを作成する方法について説明しています。私の場合は、Unit of Workをラップするインターセプタ(または2つのインターセプタ、開始用と終了用のインターセプタ)を作成したいと考えています。 AppServiceのメソッドが起動すると、spStartというストアドプロシージャを呼び出し、呼び出しがデータベースにコミットされたときにspEndを呼び出す必要があります。 ABPでUnit of Workも迎撃であるので、これは私がこれまで何をやったかである:私は上記のリンクを提供する資料の手順に従い 、私は次のようでした:ABPフレームワークのインターセプタを使用して作業ユニットをラップする方法

  • は2つのインターセプタを追加しました:StartInterceptorをし、 EndInterceptor とのRegistrarクラス
  • 私は、次のコードを追加
  • ApplicationModuleクラスApplicationModuleでも
  • でそれらを登録:

    IocManager.IocContainer.Register(Component.For<IApplicationService>() .Interceptors(InterceptorReference.ForType<StartInterceptor>()).First, Component.For<StartInterceptor>() .Interceptors(InterceptorReference.ForType<EndInterceptor>()).Last, Component.For<StopInterceptor>());

このコードは、最初StartInterceptorの実行をしなければならない、と最後に実行EndInterceptor。単位作業インターセプタが中間にあり、結果を返すためにインターセプトされた非同期メソッドを待つロジックを使用することを考慮すると、作業ユニットをラップするオプションが与えられるはずです。しかし、これが起こるのは:spStartが実行されているとき、すべてがOKです。このストアドプロシージャは、Unit of Workインターセプタの前で実行されるため、問題はありません。しかし、spEndが実行されているときは、「接続を使用してSQL文を実行する前にトランザクションを処理する」または「操作がトランザクションの状態に対して有効でない」と表示されます... UoWが私のストアドプロシージャ。他の誰かがABPと同じ問題を抱えていますか?どのように解決しましたか?

答えて

3

トランザクションの問題が発生した場合は、アクティブな接続からアクティブなトランザクションを取得する必要があります。トランザクションを取得すると、それをsqlコマンドに割り当てます。

private DbCommand CreateCommand(string commandText, CommandType commandType, params SqlParameter[] parameters) 
{ 
    var command = Context.Database.GetDbConnection().CreateCommand(); 

    command.CommandText = commandText; 
    command.CommandType = commandType; 
    command.Transaction = GetActiveTransaction(); 

    foreach (var parameter in parameters) 
    { 
     command.Parameters.Add(parameter); 
    } 

    return command; 
} 

private void EnsureConnectionOpen() 
{ 
    var connection = Context.Database.GetDbConnection(); 

    if (connection.State != ConnectionState.Open) 
    { 
     connection.Open(); 
    } 
} 

private DbTransaction GetActiveTransaction() 
{ 
    return (DbTransaction)_transactionProvider.GetActiveTransaction(new ActiveTransactionProviderArgs 
    { 
     {"ContextType", typeof(PhoneBookDbContext) }, 
     {"MultiTenancySide", MultiTenancySide } 
    }); 
} 




public async Task<GetUserByIdOutput> ExecuteMyStoredProcedure(EntityDto input) 
{ 
    EnsureConnectionOpen(); 

    using (var command = CreateCommand("SELECT dbo.GetUsernameById(@id)", CommandType.Text, new SqlParameter("@id", input.Id))) 
    { 
     var username = (await command.ExecuteScalarAsync()).ToString(); 
     return new GetUserByIdOutput() { Username = username }; 
    } 
} 

さらに詳細:https://www.codeproject.com/Articles/1199648/Using-Stored-Procedure-User-Defined-Function-and-V

+0

それは働きました!ありがとうございました。 – John

関連する問題