2017-09-30 13 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. Unit of Work 인터셉터가 중간에 있고, 결과를 리턴하기 위해 인터셉트 된 비동기 메소드를 기다리는 로직을 사용할 것이라는 점을 고려할 때, 작업 단위를 랩 할 수있는 옵션을 제공해야합니다. 그러나 이것이 발생합니다. spStart이 실행되면 모든 것이 정상입니다. 이 저장 프로시 저는 작업 단위 (UOW) 인터셉터보다 먼저 실행되기 때문에 문제가 없습니다. 그러나 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