0

是的,所以我可以很容易地创建项目,而无需在 Session.SaveOrUpdate(entity) 之后显式调用 Session.Flush() - 但更新或删除时并非如此。除了键入 Session.Flush() 我还可以键入 Session.Transaction.Commit() 来实现相同的效果(即即时删除/更新)。

这让我相信我的 NHibernateActionFilter 事务处理存在问题,即它只提交了一些时间而不是所有时间。我不太确定为什么?

品牌控制器:会话控制器

    [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");
    }

会话控制器:

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();
        }
    }
}
4

1 回答 1

1

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

您发布的代码乍一看还不错,因此问题可能在于操作过滤器的连接方式。您描述的行为也将与您的过滤器从不被调用一致(尽管在那种情况下我不知道为什么会话是打开的)。

于 2012-08-11T11:41:47.480 回答