0

POSTメソッドでトランザクションを使用したいときはいつも繰り返しているようです。アクションフィルターなどを使用できますか?

[HttpPost]
public virtual ActionResult Create(CreateModel model)
{
  if (!ModelState.IsValid)
    return View(model);

  var instruction = new Instruction(CurrentUser);
  Mapper.Map(model, instruction);

  // how do I get rid of this?
  using (var uow = _unitOfWorkFactory.Create())
  {
    _repository.Save(instruction);

    uow.SaveChanges();
  }

  return RedirectToAction("Details", new {id = instruction.Id});
}
4

1 に答える 1

1

ModelStateUnitOfWorkを作成して使用する前に、とHttpContext.Errorプロパティをチェックする新しいアクションフィルターを作成します。

public class TransactionalAttribute : ActionFilterAttribute
{
  private IUnitOfWork _unitOfWork;

  public override void OnActionExecuting(ActionExecutingContext filterContext)
  {
    if (filterContext.Controller.ViewData.ModelState.IsValid && filterContext.HttpContext.Error == null)
      _unitOfWork = DependencyResolver.Current.GetService<IUnitOfWork>();

    base.OnActionExecuting(filterContext);
  }

  public override void OnActionExecuted(ActionExecutedContext filterContext)
  {
    if (filterContext.Controller.ViewData.ModelState.IsValid && filterContext.HttpContext.Error == null && _unitOfWork != null)
      _unitOfWork.SaveChanges();

    base.OnActionExecuted(filterContext);
  }
}

UnitOfWorkのサンプルnhibernate実装(IoCに登録):

public class NhibernateUnitOfWork : IUnitOfWork
{
  private readonly ISession _session;
  private ITransaction _transaction;

  public NhibernateUnitOfWork(ISession session)
  {
    _session = session;
    _transaction = session.BeginTransaction();
  }

  public void Dispose()
  {
    if (_transaction == null)
      return;

    if (!_transaction.WasCommitted)
      _transaction.Rollback();

    _transaction.Dispose();
    _transaction = null;
  }

  public void SaveChanges()
  {
    _transaction.Commit();
  }

}

使用法:

[HttpPost, Transactional]
public virtual ActionResult Create(CreateModel model)
{
  if (!ModelState.IsValid)
    return View(model);

  var instruction = new Instruction(CurrentUser);
  Mapper.Map(model, instruction);
  _repository.Save(instruction);

  return RedirectToAction("Details", new {id = instruction.Id});
}

ソース: http: //blog.gauffin.org/2012/06/how-to-handle-transactions-in-asp-net-mvc3/

于 2012-06-05T14:24:02.683 に答える