使用 NHibernate 更改多个数据库

本文关键字:数据库 NHibernate 使用 | 更新日期: 2023-09-27 18:30:21

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

我当前的实现描述如下:

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()
        {
        }
    }
}

会话管理器实现

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. 等。

复制到实现

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

使用 NHibernate 更改多个数据库

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