2015-10-20 5 views
0

Я прочитал смесь отзывов об устройстве работы и nhibernate с питомником репозитория. Похоже, что консенсус в том, что приведенное ниже неверно при использовании в классе репозитория.UnitOfWork Nhibernate, где должен работать unitofwork

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 и UnitOfWork concreate класса впрыскивается и используется, а не используется

_portfolioRepository.UpdateCommit(entity). 

Другими словами, если хранилище имеет какое-либо отношение к организации или совершению сделки. Или это должно быть обработано в контроллере или как часть жизненного цикла приложения или процесса перехвата.

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

Ищу передовой практики NHibernate и UnitOfWork

ответ

0

В веб-приложение, устройство работы является запрос. Так что я открываю сеанс на beginrequest. У меня также есть Transaction ActionFilter, который совершает/откатывает в конце запроса. Я действительно думаю, что я собираюсь реорганизовать это по атрибутам Passive Mark Seeman и отделить атрибут от фильтра.

Ваша единица работы теперь изолирована от вашего репозитория, который должен быть абстракцией в списке предметов. В репозитории есть метод транзакции, который выдает транзакцию, если для сеанса нет текущей.

Вот начать/конец запроса

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(); 
    } 
} 

И родовое Repository

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 
} 
+0

является его дополнительные накладные расходы, чтобы открыть сессию каждый в начало и конец запрашивать, когда может не потребоваться активность базы данных? – matt

+0

NHibernate достаточно умен, чтобы не открывать соединение с базой данных, если это вам не нужно. Opensession() предназначен для быстрого вызова метода. Но некоторые из них будут созданы, так как вы все еще создаете новый объект – Fran

 Смежные вопросы

  • Нет связанных вопросов^_^