文章https://www.codeproject.com/Articles/1080517/Aspect-Oriented-Programming-using-Interceptors-wit的作者正在解释如何在" ASPNET Boilerplate"中创建一个拦截器。框架。在我的例子中,我想创建一个拦截器(或两个拦截器,一个用于Start,另一个用于End),它将包裹Unit of Work
。当任何spStart
中的方法启动时,我需要调用名为AppService
的存储过程,并在调用数据库时调用spEnd
。由于ABP中的Unit of Work
也是一个拦截器,这是我迄今为止所做的:
按照文章中的步骤我提供了上面的链接,我做了以下内容:
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
运行时,一切正常。这个存储过程在Unit of Work拦截器之前运行,因此没有问题。但是,当spEnd
运行时,它表示&#34;应该在连接可用于执行SQL语句之前处理事务&#34;或&#34;该操作对事务状态无效&#34; ...似乎UoW与我的存储过程并行运行。还有其他人与ABP有同样的问题吗?你是怎么解决的?
答案 0 :(得分: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