编辑:这个问题已经从其原始版本中被完全修改。
我的目标是在操作提交者级别提交数据库事务。我正在使用Web API .Net Framework(4.8)和Unity DI。
我的交易过滤器属性:
public class TransactionFilterAttribute : ActionFilterAttribute
{
private readonly PortalContext _context;
private DbContextTransaction _transactionScope;
public TransactionFilterAttribute(IUnityContainer container)
{
_context = container.Resolve<PortalContext>();
}
public override void OnActionExecuting(HttpActionContext actionContext)
{
_transactionScope = _context.Database.BeginTransaction();
using (_transactionScope)
{
base.OnActionExecuting(actionContext);
}
}
public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
{
try
{
base.OnActionExecuted(actionExecutedContext);
_transactionScope.Commit(); //Error occurred
}
catch (Exception ex)
{
Debug.WriteLine(ex.ToString());
}
}
}
统一配置:
public static class UnityConfig
{
private static readonly Lazy<IUnityContainer> container = new Lazy<IUnityContainer>(() =>
{
var container = new UnityContainer();
RegisterTypes(container);
return container;
});
public static IUnityContainer Container => container.Value;
private static void RegisterTypes(IUnityContainer container)
{
container.RegisterType<PortalContext>();
}
}
执行_transactionScope.Commit()
时出现错误
错误:值不能为null。参数名称:连接->基础提供程序在提交时失败。
任何帮助将不胜感激。
您可以将代码更改为如下所示。这将在调用控制器时打开事务,并在提交事务之前等待方法返回。这是通过“ await next()”部分完成的。您应该从DI容器中解析_databaseContext。如果需要,请使用此方法的同步版本。
public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
{
using (var transaction = _databaseContext.Database.BeginTransaction())
{
var result = await next();
if ((result.Exception == null || result.ExceptionHandled) &&
IsHttpSuccessStatusCode(context.HttpContext.Response.StatusCode))
{
transaction.Commit();
}
else
{
transaction.Rollback();
var controllerActionDescriptor = context.ActionDescriptor as ControllerActionDescriptor;
var controllerName = controllerActionDescriptor?.ControllerName;
var actionName = controllerActionDescriptor?.ActionName;
_logger.Error("Tried to commit transaction for the {ActionName}" +
" method on the {ControllerName} controller with the following parameters: {ActionParameters}" +
" but got exception: {Exception}",
actionName, controllerName, context.ActionArguments, result.Exception);
}
}
}