使用NHibernate更改多个数据库

时间:2012-04-05 11:27:06

标签: c# session transactions fluent-nhibernate

我在多个数据库之间复制实体时遇到问题。我似乎无法理解这个问题,并且真的需要一些实施方面的帮助。

我现在的实现在这里描述:

Http模块

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web;
using ISMSControl.Infrastructure.Sessions;
using NHibernate;
using NHibernate.Context;

namespace ISMSControl.Infrastructure.Modules
{
    public class SessionModule : IHttpModule
    {
        public void Init(HttpApplication context)
        {
            context.BeginRequest += OpenSession;
            context.EndRequest += CloseSession;
        }
        private void CloseSession(object sender, EventArgs e)
        {
            ISession session = ManagedWebSessionContext.Unbind(HttpContext.Current, SessionManager.GetCurrentSession().SessionFactory);

            if (session != null)
            {
                if (session.Transaction != null && session.Transaction.IsActive)
                    session.Transaction.Rollback();
                else
                    session.Flush();

                session.Close();
            }
        }
        private void OpenSession(object sender, EventArgs e)
        {
            ManagedWebSessionContext.Bind(HttpContext.Current,
                SessionManager.GetCurrentSession());
        }
        public void Dispose()
        {
        }
    }
}

SessionManager实施

using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web;
using FluentNHibernate.Cfg;
using FluentNHibernate.Cfg.Db;
using ISMSControl.Infrastructure.Mappings;
using NHibernate;
using NHibernate.Cache;

namespace ISMSControl.Infrastructure.Sessions
{
    public sealed class SessionManager
    {
        private const string CurrentSessionKey = "nhibernate.current_session";
        private static readonly ISessionFactory sessionFactory;

        static SessionManager()
        {
            sessionFactory = CreateSessionFactory("source");
        }

        private static ISessionFactory CreateSessionFactory(string connectionStringName)
        {
            return Fluently.Configure()
                .Database(MsSqlConfiguration.MsSql2008.ShowSql().ConnectionString(c => c.FromConnectionStringWithKey(connectionStringName)))
                .CurrentSessionContext("managed_web")
                .Cache(c =>
                {
                    c.UseQueryCache();
                    c.ProviderClass<HashtableCacheProvider>();
                })
                .Diagnostics(d =>
                {
                    d.Enable();
                    d.OutputToConsole();
                })
                .Mappings(m => m.FluentMappings.AddFromAssemblyOf<StandardMapping>())
                .BuildSessionFactory();
        }

        public static ISession GetCurrentSession()
        {
            HttpContext context = HttpContext.Current;
            ISession currentSession = context.Items[CurrentSessionKey] as ISession;

            if (currentSession == null)
            {
                currentSession = sessionFactory.OpenSession();
                context.Items[CurrentSessionKey] = currentSession;
            }

            return currentSession;
        }
        public static void CloseSession()
        {
            HttpContext context = HttpContext.Current;
            ISession currentSession = context.Items[CurrentSessionKey] as ISession;

            if (currentSession == null)
            {
                // No current session
                return;
            }
            currentSession.Close();
            context.Items.Remove(CurrentSessionKey);
        }
        public static void CloseSessionFactory(string sessionFactoryName = null)
        {
            if (sessionFactory != null)
            {
                sessionFactory.Close();
            }
        }
    }
}

存储库

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Transactions;
using System.Web;
using ISMSControl.Domain;
using ISMSControl.Domain.Contracts;
using ISMSControl.Infrastructure.Sessions;
using NHibernate;
using NHibernate.Context;

namespace ISMSControl.Infrastructure.Repositories
{
    public class StandardRepository : IStandardRepository
    {
        public void SaveOrUpdate(Standard standard)
        {
            var session = SessionManager.GetCurrentSession();

            using (var transaction = session.BeginTransaction())
            {
                session.SaveOrUpdate(standard);
                transaction.Commit();
            }
        }
        public IEnumerable<Standard> RetrieveList()
        {
            return SessionManager.GetCurrentSession().CreateCriteria<Standard>().List<Standard>();
        }
        public void CopyTo(string database, Standard standard)
        {
            //how do i implement this method, so it will copy the standard entity to the other database?
        }
    }
}

问题在于我得到了所有这些不同类型的错误,例如“会话已关闭。”,“实体低于另一个交易或某事”。 “非法企图将集合与两个公开会话相关联。”

我真的希望有人可以通过分享

帮助我指出正确的方向
  1. 教程
  2. 实施例
  3. CopyTo实施

    public void CopyTo(string sessionFactoryName, Standard standard)
        {
            //gets a new session for the destination database from the destination sessionfactory.
            using (var destinationSession = SessionFactoryContainer.Current.Get(sessionFactoryName).OpenSession())
            {
                //error: no persister for...
                var newStandard = new Standard();
                newStandard.Code = standard.Code;
                newStandard.Description = standard.Description;
                newStandard.Explanation = standard.Explanation;
    
                destinationSession.Save(newStandard);
            }
        }
    

1 个答案:

答案 0 :(得分:1)

在“CopyTo”方法中,您必须在第二个数据库上创建会话,深度克隆方法的第二个参数,然后将克隆的对象附加到您打开的会话中。