2

我目前正在使用 ASP.NET Web Api 以及 NHibernate 和 Autofac ...我遇到了一个问题,即我的更新没有提交到数据库。每次执行如下操作时,我都使用 ActionFilterAttribute 打开和关闭事务:

private ISessionFactory SessionFactory { get; set; }

public TransactionAttribute()
{
    SessionFactory = WebApiApplication.SessionFactory;
}

public override void OnActionExecuting(System.Web.Http.Controllers.HttpActionContext actionContext)
{
    var session = SessionFactory.OpenSession();
    CurrentSessionContext.Bind(session);
    session.BeginTransaction();
}

public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
{
    var session = SessionFactory.GetCurrentSession();
    var transcation = session.Transaction;
    if (transcation != null && transcation.IsActive)
    {
        transcation.Commit();
    }
    session = CurrentSessionContext.Unbind(SessionFactory);
    session.Close();
}

这适用于我的存储库中的添加、读取和删除功能。不幸的是,我的更新似乎不起作用(尽管我已经尝试了几种方法):

public bool Update(Client client)
{
    var result = Get(client.ClientID);

    if (result == null)
    {
        return false;
    }

    result.Name = client.Name;
    result.Acronym = client.Acronym;
    result.Website = client.Website;

    return true;
}

根据我所读到的,如果在事务期间修改对象,则无需手动调用 Update 或 SaveOrUpdate,因为 NHibernate 会跟踪并在事务提交时执行。

为什么我的更新功能不能正常工作?

谢谢!

4

1 回答 1

0

我自己解决了这个问题——基本上我正在创建 2 个会话(一个在我的 TranscationAttribute 中,一个由于 DI 进入我的存储库)。它创建两个的原因在 OnActionExecuting 语句中非常明确......我没有检查当前是否有任何会话工厂绑定到 CurrentSessionContext。这是我正在使用的新代码:

    public override void OnActionExecuting(System.Web.Http.Controllers.HttpActionContext actionContext)
    {
        if (!CurrentSessionContext.HasBind(SessionFactory))
        {
            CurrentSessionContext.Bind(SessionFactory.OpenSession());
        }

        var session = SessionFactory.GetCurrentSession();
        session.BeginTransaction();
    }

实现此代码后我遇到的问题是逻辑不健全..当会话被 DI 到我的存储库 ISession 中时,它没有被自动绑定。我的解决方案是将它绑定到我的存储库的构造函数中,如下所示:

    public ClientRepository(ISession session) 
    {
        if (session == null) throw new ArgumentNullException("nhSession");
        this._session = session;
        CurrentSessionContext.Bind(_session);
    }

但是我不能 100% 确定这对于许多同时的 HTTP 请求是否安全......除非有人在这里为我提供答案,否则将把这个问题带到代码审查中!

谢谢!

于 2012-10-25T19:54:40.727 回答