1

次の問題を抱えている方に感謝します。

MVC4 と NHibernate を使用してアプリケーションを開発しています。

アプリケーションはマルチデータベース接続を処理する必要があります。

各クライアントには独自のデータベースがあるため、データベース クライアントに接続する初期ログイン フォームがあります。資格情報が確認されたら、特定のクライアント データベースへの接続を確立する必要があります。

私たちはこの問題に数日間取り組んできましたが、これが現在取り組んでいる解決策です。

SessionFactory Dictionary を使用して、global.asax にプロパティを作成しました。クライアントがログインするたびに、新しい SessionFactory をディクショナリに追加します。

次のように、nhibernate セッションのバインドとバインド解除をすべてのアクションで制御するための ActionFilter を作成しました。

  public class SessionPerRequest : ActionFilterAttribute   {

    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        Boreas.Subsistemas.Cliente.VO.Nuestro_ClienteVO cliente = (Boreas.Subsistemas.Cliente.VO.Nuestro_ClienteVO)filterContext.HttpContext.Session["Cliente"];

        NHibernate.ISession session = MvcApplication.getSession(cliente).OpenSession();

        session.BeginTransaction();

        CurrentSessionContext.Bind(session);
    }

    public override void OnResultExecuted(ResultExecutedContext filterContext)
    {
        Boreas.Subsistemas.Cliente.VO.Nuestro_ClienteVO cliente = (Boreas.Subsistemas.Cliente.VO.Nuestro_ClienteVO)filterContext.HttpContext.Session["Cliente"];

        NHibernate.ISession session = CurrentSessionContext.Unbind(MvcApplication.getSession(cliente));

        if (session != null)
        {
            if (session.Transaction.IsActive)
            {
                try
                {
                    session.Transaction.Commit();
                }
                catch
                {
                    session.Transaction.Rollback();
                }
            }

            session.Close();
        }

        MvcApplication.removeSession(cliente);
    }
}

これらは、セッション ファクトリを作成、削除し、各クライアントに返す global.asax のメソッドです。

public static void addSession(Boreas.Subsistemas.Cliente.VO.Nuestro_ClienteVO cliente)
    {
        if (!DictionarySessionFactory.ContainsKey(cliente))
        {
            ISessionFactory Session;
            var nhibernateConiguration = new NHibernate.Cfg.Configuration();
            nhibernateConiguration.SetProperty("connection.connection_string",    cliente.baseDatosClienteBoreas);

            nhibernateConiguration.Configure();
            SessionFactory = nhibernateConiguration.BuildSessionFactory();           
        }          
    }

    public static void removeSession(Boreas.Subsistemas.Cliente.VO.Nuestro_ClienteVO cliente)
    {
        if (cliente != null)
        {
            if (DictionarySessionFactory.ContainsKey(cliente))
            {
                DictionarySessionFactory.Remove(cliente);
            }
        }
    }

    public static ISessionFactory getSession(Boreas.Subsistemas.Cliente.VO.Nuestro_ClienteVO cliente)
    {
        ISessionFactory Session;

        if (cliente == null)
        {               
            var nhibernateConiguration = new NHibernate.Cfg.Configuration();
            nhibernateConiguration.SetProperty("connection.connection_string", "Data Source=BENITO-PC\\WINCODICE;Initial Catalog=ClientesBoreasRutas;User ID=sa;Password=2144;");

            nhibernateConiguration.Configure();
            Session = nhibernateConiguration.BuildSessionFactory();
            //DictionarySessionFactory.Add(null, Session);
            return Session;
        }
        else {
            if (DictionarySessionFactory.ContainsKey(cliente))
            {
                return DictionarySessionFactory[cliente];
            }
            else
            {
                var nhibernateConiguration = new NHibernate.Cfg.Configuration();
                nhibernateConiguration.SetProperty("connection.connection_string", cliente.baseDatosClienteBoreas);
                nhibernateConiguration.Configure();
                Session = nhibernateConiguration.BuildSessionFactory();
                DictionarySessionFactory.Add(cliente, Session);
                return SessionFactory;               
            }

        }               

    }

問題は、アプリケーションがNhibernate.HibernateException "No session bound to the current context" を返すことです。

問題を解決するための助けをいただければ幸いです。また、Nhibernate と mvc4 を使用して複数のデータベース接続を実装する他の適切な方法を聞くことも興味深いでしょう。

私の投稿を読んでくれてありがとう

4

1 に答える 1

0

OnResultExecuted メソッドでは、次の行はありません。

NHibernate.ISession session = CurrentSessionContext.Unbind(MvcApplication.getSession(cliente));

トランザクションがコミットされる前に、現在のコンテキストからトランザクションをバインド解除しますか? セッションが終了すると、この行が表示されます。

トランザクションをコミットする前に、(SessionFactory で GetCurrentSession() を呼び出して) セッションを取得し、トランザクションをコミットしてからアンバインドする必要があります。

于 2013-08-08T14:09:25.610 に答える