每个请求的nHibernate会话和异常管理

每个请求的nHibernate会话和异常管理,nhibernate,exception,session-per-request,Nhibernate,Exception,Session Per Request,我有一个类似的场景: Asp.NET MVC 4网站,每个请求使用nHibernate会话。 使用Ninject将会话注入到具有Get和Save方法的存储库中 有很多文章都在讨论每个请求的会话,并说这是在web应用程序上执行操作的方法 但我在实现这样的逻辑时遇到了问题: Read Data From Database Alter Entity information Save to Database Read another entity Alter entity Save ... but an

我有一个类似的场景: Asp.NET MVC 4网站,每个请求使用nHibernate会话。 使用Ninject将会话注入到具有Get和Save方法的存储库中

有很多文章都在讨论每个请求的会话,并说这是在web应用程序上执行操作的方法

但我在实现这样的逻辑时遇到了问题:

Read Data From Database
Alter Entity information
Save to Database
Read another entity
Alter entity
Save ... but an EXCEPTION OCCURS
我想用一条消息向用户显示我的视图。但我还需要刷新生成的网页, 所以我还要从数据库中读取一些信息

根据nHibernate文档,除了异常,会话必须被丢弃

但是我找不到任何关于最好的方法的文章

解决这种情况的最佳方法是什么?。我必须向我的存储库对象?注入一个新会话


谢谢。

您可以从原始会话的SessionFactory属性创建新会话。您可以通过在repository类中公开原始会话对象或将其注入控制器来访问它。然后,您可以使用新会话创建一个新存储库

在我的一些操作中,我希望发生唯一的密钥冲突,并且我必须在模型中重新加载查找数据。下面是一个例子:

    public ActionResult Create(MeasuresEditView model)
    {
        if (ModelState.IsValid)
        {
            using (var txn = _session.BeginTransaction())
            {
                try
                {
                    var measure = new Measure { Code = model.Code };
                    _session.Save(measure);
                    txn.Commit();
                    return RedirectToAction("Index");
                }
                catch (UniqueKeyException)
                {
                    txn.Rollback();
                    var msg = string.Format("A measure with the code '{0}' already exists, please enter a different code or cancel.", model.Code);
                    ModelState.AddModelError("Code", msg);
                }
                catch (Exception ex)
                {
                    if (txn.IsActive)
                    {
                        txn.Rollback();
                    }
                    log.Error("Create", ex);
                    throw;
                }
            }
        }
        // have to rebuild selectlist on post in new txn in case it was rolled back
        using (var session = _session.SessionFactory.OpenSession())
        using (var txn = session.BeginTransaction())
        {
            SetProductGroupSelectList(session, model, manualId);
            txn.Commit();
        }
        return View(model);
    }

谢谢,我将使用它作为解决方案的基准。我将尝试将其与存储库和工作单元模式集成。