2017-09-30 53 views
0

文章https://www.codeproject.com/Articles/1080517/Aspect-Oriented-Programming-using-Interceptors-wit的作者正在解釋如何在「ASPNET Boilerplate」框架中創建攔截器。在我的情況下,我想創建一個攔截器(或兩個攔截器,一個用於開始,另一個用於結束),它將包裝Unit of Work。當任何AppService中的方法啓動時,我需要調用一個名爲spStart的存儲過程,並在調用數據庫時調用spEnd。由於在ABP的Unit of Work也是一個攔截器,這是我迄今所做的: 按照我提供上面的鏈接的文章中的步驟,我做了以下內容:如何在ABP框架中用攔截器包裹工作單元

  • 增加了兩個攔截器:StartInterceptorEndInterceptor與 他們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運行時,一切都很好。該存儲過程在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