我已经阅读了关于工作单元和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
答案 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
}