How to use NHibernate with both MySQL server and Microsoft SQL server 2008

后端 未结 2 1236
慢半拍i
慢半拍i 2021-01-29 03:44

How can I configure NHibernate to connect to both a MySQLserver and a Microsoft SQL server 2008? I do want to copy data from one server to another. I heard of NHibernate shared.

相关标签:
2条回答
  • 2021-01-29 04:34

    I've struggled quite a bit few months ago. My problem was with MS Sql Server and Oracle.

    What I've done is to create two separate config files for nhibernate:

    sql.nhibernate.config

    <?xml version="1.0" encoding="utf-8"?>
        <hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">
          <reflection-optimizer use="false" />
          <session-factory name="BpSpedizioni.MsSql">
            <property name="connection.provider">NHibernate.Connection.DriverConnectionProvider</property>
            <property name="connection.driver_class">NHibernate.Driver.SqlClientDriver</property>
            <property name="dialect">NHibernate.Dialect.MsSql2008Dialect</property>
            <!-- <property name="connection.connection_string">Data Source=(local); Initial Catalog=NHibernate; Trusted_Connection=true;</property> -->
            <property name="current_session_context_class">web</property>
            <property name="adonet.batch_size">100</property>
            <property name="command_timeout">120</property>
            <property name="max_fetch_depth">3</property>
            <property name='prepare_sql'>true</property>
            <property name="query.substitutions">true 1, false 0, yes 'Y', no 'N'</property>
            <property name='proxyfactory.factory_class'>NHibernate.ByteCode.Castle.ProxyFactoryFactory, NHibernate.ByteCode.Castle</property>
            <mapping assembly="BpSpedizioni.Services"/>
          </session-factory>
    </hibernate-configuration>
    

    ora.nhibernate.config

    <?xml version="1.0" encoding="utf-8"?>
    <hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">
      <reflection-optimizer use="false" />
      <session-factory name="BpSpedizioni.Oracle">
        <property name="connection.provider">NHibernate.Connection.DriverConnectionProvider</property>
        <property name="connection.driver_class">NHibernate.Driver.OracleDataClientDriver</property>
        <property name="dialect">NHibernate.Dialect.Oracle10gDialect</property>
        <!-- <property name="connection.connection_string">Data Source=(local); Initial Catalog=NHibernate; Trusted_Connection=true;</property> -->
        <property name="current_session_context_class">web</property>
        <property name="adonet.batch_size">100</property>
        <property name="command_timeout">120</property>
        <property name="max_fetch_depth">3</property>
        <property name='prepare_sql'>true</property>
        <property name="query.substitutions">true 1, false 0, yes 'Y', no 'N'</property>
        <property name='proxyfactory.factory_class'>NHibernate.ByteCode.Castle.ProxyFactoryFactory, NHibernate.ByteCode.Castle</property>
        <mapping assembly="BpSpedizioni.Services"/>
      </session-factory>
    </hibernate-configuration>
    

    I use this simple class to build my nhibernate SessionFactory:

        public class NHibernateSessionFactory
        {
            private ISessionFactory sessionFactory;
    
            private readonly string ConnectionString = "";
            private readonly string nHibernateConfigFile = "";
    
            public NHibernateSessionFactory(String connectionString, string nHConfigFile)
            {
                this.ConnectionString = connectionString;
                this.nHibernateConfigFile = nHConfigFile;
            }
    
            public ISessionFactory SessionFactory
            {
                get { return sessionFactory ?? (sessionFactory = CreateSessionFactory()); }
            }
    
            private ISessionFactory CreateSessionFactory()
            {
                Configuration cfg;
                cfg = new Configuration().Configure(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, this.nHibernateConfigFile));
    
                // With this row below Nhibernate searches for the connection string inside the App.Config.
                // cfg.SetProperty(NHibernate.Cfg.Environment.ConnectionStringName, System.Environment.MachineName);
                cfg.SetProperty(NHibernate.Cfg.Environment.ConnectionString, this.ConnectionString);
    
    #if DEBUG
                cfg.SetProperty(NHibernate.Cfg.Environment.GenerateStatistics, "true");
                cfg.SetProperty(NHibernate.Cfg.Environment.ShowSql, "true");
    #endif
    
                return (cfg.BuildSessionFactory());
            }
        }
    

    As you can see I pass to my NHibernateSessionFactory a connection string (I prefer to save it in my app config file) and the name (without the path) of the nhibernate config file.

    I personally use a DI container (StructureMap) and you can achieve something very cool defining a registry class:

    public class NhibernateRegistry : Registry
    {
        public NhibernateRegistry()
        {
    
            For<ISessionFactory>()
            .Singleton()
            .Add(new NHibernateSessionFactory(<oracle connection string>, "ora.nhibernate.config").SessionFactory)
            .Named("OracleSF");
    
            For<ISession>()
            .HybridHttpOrThreadLocalScoped()
            .Add(o => o.GetInstance<ISessionFactory>("OracleSF").OpenSession())
            .Named("OracleSession");
    
            For<ISessionFactory>()
            .Singleton()
            .Add(new NHibernateSessionFactory(<ms sql connection string>, "sql.nhibernate.config").SessionFactory)
            .Named("MsSqlSF");
    
            For<ISession>()
            .HybridHttpOrThreadLocalScoped()
            .Add(o => o.GetInstance<ISessionFactory>("MsSqlSF").OpenSession())
            .Named("MsSqlSession");
        }
    }
    

    in which you can use named instances. My services layer than uses a StructureMap registry class where you can define the constructors:

    this.For<IOrdersService>()
         .HybridHttpOrThreadLocalScoped()
         .Use<OrdersService>()
         .Ctor<ISession>("sessionMDII").Is(x => x.TheInstanceNamed("OracleSession"))
         .Ctor<ISession>("sessionSpedizioni").Is(x => x.TheInstanceNamed("MsSqlSession"));
    

    For your Service implementation:

    public class OrdersService : IOrdersService
    {
            private readonly ISession SessionMDII;
            private readonly ISession SessionSpedizioni;
    
            public OrdersService(ISession sessionMDII, ISession sessionSpedizioni)
            {
                this.SessionMDII = sessionMDII;
                this.SessionSpedizioni = sessionSpedizioni;
            }
    
        ...
    }
    
    0 讨论(0)
  • It's not clear what your use case is, but you will simply need to create 2 session factories. One will use your mySQL dialect, connection string, etc... and the other will use the SQL Server equivalents.

    Just avoid including any custom SQL in your mappings and this should work fine.

    0 讨论(0)
提交回复
热议问题