UnitOfWork Nhibernate应该在哪里进行单元工作

时间:2015-10-20 22:13:38

标签: nhibernate unit-of-work

我已经阅读了关于工作单元和nhibernate的评论的混合物和存储库文件。在存储库类中使用时,以下内容似乎是不正确的。

public void UpdateCommit(T entity)
{
    using (ITransaction transaction = Session.BeginTransaction())
    {
         Session.Update(entity);
         transaction.Commit();
    }
 }

我的理解是存储库应该只包含

public void Update(T entity)
{
    Session.Update(entity);
}

然后我为我的工作单元开了另一个班。

在我的控制器中注入工作单元然后运行以下代码是否正确:

_unitOfWork.BeginTransaction();
_portfolioRepository.Create(Mapper.Map<Portfolio>(model));
_unitOfWork.Commit();

实际上我的网络应用程序和我保存数据的地方有一个portfoliorepository和一个单元工作concreate类注入和使用而不是使用

 _portfolioRepository.UpdateCommit(entity).

换句话说,存储库是否与单元工作或提交事务有关。或者应该在控制器中处理,还是作为应用程序生命周期或拦截过程的一部分来处理。

http://www.codeproject.com/Articles/543810/Dependency-Injection-and-Unit-Of-Work-using-Castle

我正在寻找最佳实践nhibernate和unitofwork

1 个答案:

答案 0 :(得分:0)

在Web应用程序中,您的工作单元就是请求。所以我所做的是开始一个关于beginrequest的会议。我还有一个Transaction ActionFilter,它在请求结束时提交/回滚。我确实认为我会根据Mark Seeman的被动属性重构这一点,并将属性与过滤器分开。

您的工作单元现在与您的存储库隔离,该存储库应该是项目列表的抽象。存储库有一个transact方法,如果当前没有会话,它会旋转一个事务。

这里是开始/结束请求

    protected void Application_BeginRequest() { CurrentSession = SessionFactory.OpenSession(); }

    protected void Application_EndRequest()
    {
        if (CurrentSession != null)
            CurrentSession.Dispose();
    }

这里是属性

[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class)]
public class TransactionAttribute : ActionFilterAttribute
{
    private ITransaction Transaction { get; set; }

    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        Transaction = MvcApplication.CurrentSession.BeginTransaction(IsolationLevel.ReadCommitted);
    }

    public override void OnActionExecuted(ActionExecutedContext filterContext)
    {
        if (!Transaction.IsActive) return;

        if (filterContext.Exception == null)
        {
            Transaction.Commit();
            return;
        }

        Transaction.Rollback();
    }
}  

和通用存储库

public class Repository<T> : IRepository<T> where T : EntityBase
{
    private readonly ISession _session;

    #region constructor

    public Repository(ISession session)
    {
        _session = session;
    }

    #endregion

    #region Transact

    protected virtual TResult Transact<TResult>(Func<TResult> func)
    {
        if (_session.Transaction.IsActive)
            return func.Invoke();

        TResult result;
        using (var tx = _session.BeginTransaction(IsolationLevel.ReadCommitted))
        {
            result = func.Invoke();
            tx.Commit();
        }

        return result;
    }

    protected virtual void Transact(System.Action action)
    {
        Transact(() =>
        {
            action.Invoke();
            return false;
        });
    }

    #endregion

    #region IRepository<T> Members

    public void Save(T item)
    {
        Transact(() => _session.Save(item));
    }

    public Boolean Contains(T item)
    {
        if (item.Id == default(Guid))
            return false;

        return Transact(() => _session.Get<T>(item.Id)) != null;
    }

    public Int32 Count
    {
        get
        {
            return Transact(() => _session.Query<T>().Count());
        }
    }

    public bool Remove(T item)
    {
        Transact(() => _session.Delete(item));
        return true;
    }

    public T Load(Guid id)
    {
        return Transact(() => _session.Load<T>(id));
    }

    public T Get(Guid id)
    {
        return Transact(() => _session.Get<T>(id));
    }

    public IQueryable<T> FindAll()
    {
        return Transact(() => _session.Query<T>());
    }

    #endregion

    #region IEnumerable<T> Members

    public IEnumerator<T> GetEnumerator()
    {
        return Transact(() => _session.Query<T>().Take(1000).GetEnumerator());
    }

    #endregion

    #region IEnumerable Members

    IEnumerator IEnumerable.GetEnumerator()
    {
        return Transact(() => GetEnumerator());
    }

    #endregion
}