2

現在、NHibernate と Autofac と共に ASP.NET Web API を使用しています...更新がデータベースにコミットされないという問題があります。次のように、アクションが実行されるたびに、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;
}

トランザクション中にオブジェクトを変更する場合に読んだことから、これは NHibernate によって追跡され、トランザクションがコミットされたときに実行されるため、Update または SaveOrUpdate を手動で呼び出す必要はありません。

更新機能が正しく動作しないのはなぜですか?

ありがとう!

4

1 に答える 1

0

私はこれを自分で理解しました-基本的に私は2つのセッションを作成していました(1つはTranscationAttributeにあり、もう1つはリポジトリへのDIによるものです)。2つ作成した理由は、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();
    }

このコードを実装した後に私が抱えていた問題は、ロジックが正しくないことです。セッションがリポジトリISessionにDIされたとき、自動的にバインドされていませんでした。私の解決策は、次のようにリポジトリのコンストラクターにバインドすることでした。

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

しかし、これが多くの同時HTTPリクエストで安全であるかどうかは、100%確信していません...誰かがここで私に答えを持っていない限り、この質問をコードレビューに持ち込むつもりです!

ありがとう!

于 2012-10-25T19:54:40.727 に答える