Mysql
 sql >> Database >  >> RDS >> Mysql

Come utilizzare NHibernate sia con il server MySQL che con il server Microsoft SQL 2008

Ho lottato parecchi mesi fa. Il mio problema riguardava MS Sql Server e Oracle.

Quello che ho fatto è creare due file di configurazione separati per 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>

Uso questa semplice classe per costruire la mia SessionFactory nhibernate:

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

Come puoi vedere passo alla mia NHibernateSessionFactory una stringa di connessione (preferisco salvarla nel file di configurazione della mia app) e il nome (senza il percorso) del file di configurazione di nhibernate.

Personalmente uso un contenitore DI (StructureMap) e puoi ottenere qualcosa di molto interessante definendo una classe di registro:

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 cui è possibile utilizzare istanze denominate. Il livello dei miei servizi utilizza una classe di registro StructureMap in cui è possibile definire i costruttori:

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

Per l'implementazione del servizio:

public class OrdersService : IOrdersService
{
        private readonly ISession SessionMDII;
        private readonly ISession SessionSpedizioni;

        public OrdersService(ISession sessionMDII, ISession sessionSpedizioni)
        {
            this.SessionMDII = sessionMDII;
            this.SessionSpedizioni = sessionSpedizioni;
        }

    ...
}