NHibernate Session / Transaction Woes

时间:2012-03-13 16:24:40

标签: nhibernate session transactions

我正在尝试使用每个请求的会话模式,并且在保存后立即获取记录时遇到问题。这样做的原因是我需要获取外键所关联的记录。

一些(简化的)代码:

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

2 个答案:

答案 0 :(得分:1)

在您刷新会话或减少事务范围之前,您将没有ID,因为nhibernate不会插入记录。

答案 1 :(得分:1)

一个选项,将您的ID策略从数据库中生成的标识更改为由NHibernate管理的标识(请参阅http://nhibernate.info/doc/nh/en/index.html#mapping-declaration-id-generator处的选项)或其他选项将会话的flushmode更改为FlushMode.Auto。