我正在尝试使用每个请求的会话模式,并且在保存后立即获取记录时遇到问题。这样做的原因是我需要获取外键所关联的记录。
一些(简化的)代码:
// UnitOfWork Attribute
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
SessionFactory.Begin();
}
public override void OnResultExecuted(ResultExecutedContext filterContext)
{
if (filterContext.Exception == null) {
try {
SessionFactory.Commit();
} catch {
SessionFactory.Rollback();
throw;
}
} else {
SessionFactory.Rollback();
throw filterContext.Exception;
}
}
// Service layer
public void Save(Form form)
{
_repository.Save(form);
var savedForm = _repository.Get(form.Id);
SendEmail(savedForm);
}
// Repository
public void Save(Form form)
{
var session = SessionFactory.CurrentSession;
session.SaveOrUpdate(form);
}
问题在于,当我尝试获取记录时,事务尚未提交,因此它只是告诉我会话中已有的内容。我是否只需要在保存后提交交易,并打开一个新的交易来获取它?
由于
更新
我实施了Agathas Storefront的服务方式,让服务层控制交易,即:
public class UnitOfWork : IUnitOfWork
{
public void Commit()
{
var session = SessionFactory.CurrentSession;
using (ITransaction transaction = session.BeginTransaction())
{
try {
transaction.Commit();
} catch {
transaction.Rollback();
throw;
}
}
}
public void Clear()
{
var session = SessionFactory.CurrentSession;
session.Clear();
}
}
然后在服务层:
public void SaveForm(Form form)
{
_repository.Save(form);
_uow.Commit();
_uow.Clear();
var savedForm = _repository.Get(form.Id);
SendEmail(savedForm);
}
更新2
好的,我想我找到了合适的解决方案。我已经回到了每个请求的事务模式,在保存表单后,我现在正在刷新它,然后从会话中逐出表单,以迫使NH从数据库中获取它。
// Service layer
public void SaveForm(Form form)
{
_repository.Save(form);
var savedForm = _repository.Get(form.Id);
SendEmail(savedForm);
}
// Repository
public void Save(Form form)
{
var session = SessionFactory.CurrentSession;
session.SaveOrUpdate(form);
session.Flush();
session.Evict(form);
}
答案 0 :(得分:1)
在您刷新会话或减少事务范围之前,您将没有ID,因为nhibernate不会插入记录。
答案 1 :(得分:1)
一个选项,将您的ID策略从数据库中生成的标识更改为由NHibernate管理的标识(请参阅http://nhibernate.info/doc/nh/en/index.html#mapping-declaration-id-generator处的选项)或其他选项将会话的flushmode更改为FlushMode.Auto。