NHibernate会话/事务难题

NHibernate会话/事务难题,nhibernate,session,transactions,Nhibernate,Session,Transactions,我尝试使用每请求会话模式,但在保存记录后立即获取记录时遇到了问题。这样做的原因是我需要获取外键相关的记录 一些(简化)代码: 问题是,当我尝试获取记录时,事务还没有提交,所以它只提供会话中已经存在的内容。我是否只需要在保存后提交事务,然后打开一个新事务来获取它 谢谢 更新: 我已经实现了Agathas店面处理事务的方式,让服务层控制事务,即: public class UnitOfWork : IUnitOfWork { public void Commit() {

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

一些(简化)代码:

问题是,当我尝试获取记录时,事务还没有提交,所以它只提供会话中已经存在的内容。我是否只需要在保存后提交事务,然后打开一个新事务来获取它

谢谢

更新:

我已经实现了Agathas店面处理事务的方式,让服务层控制事务,即:

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从DB中获取表单

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

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

一个选项,将您的ID策略从数据库中生成的标识更改为由nhibernate管理的标识(请参阅中的选项)或者另一个选项将会话的flushmode更改为flushmode.Auto。

您是列ID的标识列吗?我是,但这并不是我的主要问题(即使这仍然是一个问题)。我的主要问题是无法加载外键记录。也许延迟加载可以解决这个问题?这是你的问题,身份是你的敌人,尤其是当你使用一个工作单元时。如果实体没有首先发送到数据库,它是如何获取ID的?我理解你的意思,但是正如我对第四名所说的,这是一个我正在转换为NH的项目,所以现在更改生成ID的方式将是一个坏主意。无论如何,我已经发布了第二次更新,解决了这个问题。我不是说你应该改变,也不是说你应该改变,我只是说身份对于uow实现来说不是那么好。谢谢。session.Refresh()似乎不起作用,尽管session.Clear()起作用。最后,我稍微改变了工作单元模式,让服务层控制事务,而不是像Agathas Storefront项目那样每个请求都有事务。如果您自己分配ID,您可以每个请求都有事务(hilo或GUI很好,已经有了相应的算法).问题是,这是一个我正在转换为NHibernate的项目,所以我真的不想开始乱搞数据库中已经存在的ID。是的,那会很艰难。我同意这不是一个好主意。我仍然不太喜欢使用我在上面发布的Agathas店面示例,但我想现在必须这样做。在NHibernate中,似乎有很多方法可以管理会话/事务,但我仍然没有找到理想的解决方案。感谢您的建议,但我宁愿坚持使用数据库中生成的标识。
// 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);
}