是否必须在更新后显式调用Session.Flush()并删除我的应用程序更大问题的迹象?

时间:2012-08-10 14:44:51

标签: asp.net-mvc-3 nhibernate session transactions

是的,所以我可以非常轻松地创建项,而不必在Session.SaveOrUpdate(实体)之后显式调用Session.Flush() - 但是更新或删除时不是这样。我也可以输入Session.Transaction.Commit()来实现相同的效果(即即时删除/更新),而不是键入Session.Flush()。

这让我相信我的NHibernateActionFilter事务处理存在问题,即它只提交某些的时间而不是一直提交。我不太清楚为什么?

BrandController:SessionController

    [HttpPost]
    public ActionResult Edit (EditBrandViewModel editBrandViewModel)
    {
        if(ModelState.IsValid)
        {
            var model = editBrandViewModel;
            var brand = Session.Get<Brand>(model.Id);

            Mapper.Map(model, brand);
            Session.SaveOrUpdate(brand);
            Session.Flush();
            return RedirectToAction("Details/" + model.Id);
        }

        return View(editBrandViewModel);
    }

    public ActionResult Delete(int id)
    {
        var brand = Session.Get<Brand>(id);
        Session.Delete(brand);
        Session.Flush();
        return RedirectToAction("Index");
    }

SessionController:

public class SessionController : Controller
{
    public HttpSessionStateBase HttpSession
    {
        get { return base.Session; }
    }

    public new ISession Session { get; set; }
}  

NHibernateActionFilter:

public class NHibernateActionFilter : ActionFilterAttribute
{
    private static ISessionFactory sessionFactory;

    public NHibernateActionFilter(ISessionFactory sessionFactory)
    {
        sessionFactory = sessionFactory;
    }

    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        var sessionController = filterContext.Controller as SessionController;

        if (sessionController == null)
            return;

        sessionController.Session = sessionFactory.OpenSession();
        sessionController.Session.BeginTransaction();
    }

    public override void OnActionExecuted(ActionExecutedContext filterContext)
    {
        var sessionController = filterContext.Controller as SessionController;

        if (sessionController == null)
            return;

        using (var session = sessionController.Session)
        {
            if (session == null)
                return;

            if (!session.Transaction.IsActive)
                return;

            if (filterContext.Exception != null)
                session.Transaction.Rollback();
            else
                session.Transaction.Commit();
        }
    }
}

1 个答案:

答案 0 :(得分:1)

如果没有显式事务,Inserts可能会立即在NHibernate中触发,具体取决于您如何映射标识列。这是因为NHibernate在调用Save / SaveOrUpdate后希望他/她的实体拥有有效的Id值。像“身份”这样的数据库生成策略必须在执行SaveOrUpdate时立即触发它,但像“guid”这样的策略将等到你刷新。

您发布的代码乍一看似乎没问题,因此问题可能在于操作过滤器的连接方式。您描述的行为也与您从未调用的过滤器一致(尽管在这种情况下我不知道会话打开的原因)。