6

我一直在看这个名为“NHibernate 和工作单元模式”的优秀博客,并且有一个关于在 asp.net mvc 项目中使用 UnitOfWork.Start 的最佳位置的问题。

我的 SLN 分为以下项目:-

 MVC project
 Repository
 NHibernateUnitOfWork

我有一个界面: -

 public interface INameRepository
 ...
       IList<Name> GetByOrigin(int OriginId)
 ...

我有一个具体的实现

     public class NameRepository : INameRepository
     ...
          public  IList<Name> GetByOrigin(int OriginId) {
                using (UnitOfWork.Start()) {
                     var query = session.Linq<...
                     return query;
                }
          }
     ...

我的问题是我是否使用 using(UnitOfWork.Start()) 将所有方法包装在所有存储库中,还是有更好的方法?

我正在使用 nHibernate,asp.net mvc。

4

2 回答 2

4

使用工作单元模式,您不会将每个数据访问方法放在一个单独的工作单元中。您可以围绕需要完成的整个工作使用工作单元,在大多数情况下,在 web 应用程序中是 webrequest。这个想法是请求可以失败或成功。当您在一个请求期间向数据库添加 2 个项目时,应该同时添加或不添加。不只是其中之一。在大多数情况下,在 mvc(或其他 Web)应用程序中启动工作单元的最简单方法是使用 global.asax 的开始和结束请求方法

class Global
{
    BeginRequest()
    {
        servicelocater.get<unitofwork>().start();
    }

    EndRequest()
    {
        var unit = servicelocater.Get<Unitofwork>();
        try
        {
            unit.commit();
        }
        catch
        {
            unit.rollback();
            throw;
        }
    }
}

class Repository<T>
{
     public Repository(INHibernateUnitofwork unitofwork)
     {
         this.unitofwork = unitofwork;
     }

     public void Add(T entity)
     {
         unitofwork.session.save(entity);
     }
}
于 2009-12-30T20:16:06.757 回答
2

我认为夏普架构很好地解决了这个问题。他们所做的是将工作单元放入 ASP .Net MVC 动作过滤器中。基本上您可以定义一个事务操作过滤器,例如


public class TransactionAttribute : ActionFilterAttribute
{
      public override void OnActionExecuting(ActionExecutingContext filterContext)
      {
         UnitOfWork.Start();
      }

      public override void OnActionExecuted(ActionExecutedContext filterContext)
      {
         UnitOfWork.Stop();
      }
}

并在您的控制器类中将 Transaction 属性放在您的 Action Result 方法上

于 2009-12-30T19:33:57.357 回答