Rohit Gupta

Engaging talk on Microsoft Technologies ....My Resume

  Home  |   Contact  |   Syndication    |   Login
  43 Posts | 0 Stories | 42 Comments | 0 Trackbacks

News



Twitter












Archives

Image Galleries

Personal

To use SQL Azure Federations with NHibernate we need to insure that we reuse the connection that was used for executing the USE Federation command.
Secondly we need to insure that we don’t enlist the “use Federation” command in a transaction.
For this purpose I have created a helper class named NHibernateSession which has a parameterized constructor which opens a connection and then associates that connection with the NHibernate ISession.

The NHibernateSession class looks like the following:

   1: public class NHibernateSession : IDisposable
   2:    {
   3:        private readonly ITransaction _transaction;
   4:        private readonly IDbConnection _connection;
   5:  
   6:        public NHibernateSession(bool beginTran, IDbConnection connection = null)
   7:        {
   8:            if (connection != null && connection.State == ConnectionState.Closed)
   9:            {
  10:                connection.Open();
  11:                _connection = connection;
  12:            }
  13:  
  14:            if (CurrentSessionContext.HasBind(NHibernateBootstrapper.SessionFactory))
  15:            {
  16:                NHibernateWorkspace.CurrentSession = NHibernateBootstrapper.SessionFactory.GetCurrentSession();
  17:            }
  18:            else
  19:            {
  20:                NHibernateWorkspace.CurrentSession = connection != null ? 
  21:                    NHibernateBootstrapper.SessionFactory.OpenSession(connection) : 
  22:                    NHibernateBootstrapper.SessionFactory.OpenSession();
  23:  
  24:                CurrentSessionContext.Bind(NHibernateWorkspace.CurrentSession);
  25:            }
  26:            if(beginTran)
  27:                _transaction = NHibernateWorkspace.CurrentSession.BeginTransaction();
  28:        }
  29:  
  30:        public NHibernateSession(int customerId, string connString) : this(false, new SqlConnection(connString))
  31:        {
  32:            var sql = string.Format("USE FEDERATION Customer_Federation(CustID = {0}) WITH RESET, FILTERING = ON;", customerId);
  33:            var query = NHibernateWorkspace.CurrentSession.CreateSQLQuery(sql);
  34:            query.UniqueResult();
  35:            _transaction = NHibernateWorkspace.CurrentSession.BeginTransaction();
  36:        }
  37:  
  38:        public NHibernateSession(): this(true)
  39:        {
  40:            
  41:        }
  42:  
  43:        public void Dispose()
  44:        {
  45:            Dispose(true);
  46:            GC.SuppressFinalize(this);
  47:        }
  48:  
  49:        // The bulk of the clean-up code is implemented in Dispose(bool)
  50:        protected virtual void Dispose(bool disposing)
  51:        {
  52:            if (disposing)
  53:            {
  54:                try
  55:                {
  56:                    if(_transaction != null)
  57:                        _transaction.Commit();
  58:                    if(_connection != null && _connection.State != ConnectionState.Closed)
  59:                        _connection.Close();
  60:                }
  61:                catch
  62:                {
  63:                    if (_transaction != null)
  64:                        _transaction.Rollback();
  65:                    throw;
  66:                }
  67:                finally
  68:                {
  69:                    // free managed resources
  70:                    CurrentSessionContext.Unbind(NHibernateBootstrapper.SessionFactory);
  71:                    NHibernateWorkspace.CurrentSession.Dispose();
  72:                }
  73:            }
  74:        }
  75:    }

Thus we could instantiate this NHibernateSession from within our Repositories/MVC Controllers as the following:
   1: var connstring = ConfigurationManager.ConnectionStrings["AdventureWorks2008R2EntitiesNoMARS"].ConnectionString;
   2: using (var ctx = new NHibernateSession(29825, connString))
   3: {
   4:     var sql = "SELECT COUNT(*) FROM Sales.SalesOrderDetail";
   5:     var query = NHibernateWorkspace.CurrentSession.CreateSQLQuery(sql);
   6:     var orderCount = query.UniqueResult();
   7: }

For code completeness I have included the code for the NHibernateBootstrapper which sets up the NHibernate Session Factory using Fluent NHibernate config:
   1: public class NHibernateBootstrapper
   2: {
   3:     private static readonly ISessionFactory SessionFactoryMember;
   4:     static NHibernateBootstrapper()
   5:     {
   6:         var allAssemblies = Assembly.GetExecutingAssembly().GetReferencedAssemblies().ToList();
   7:  
   8:         var autoConfig = new AutoMapConfiguration();
   9:         var persistenceModel = AutoMap.Assemblies(autoConfig, allAssemblies)
  10:             .Conventions.AddFromAssemblyOf<ClassConvention>()
  11:             .OverrideAll(m => m.IgnoreProperty("RowVersion"));
  12:  
  13:         foreach (var assembly in allAssemblies)
  14:         {
  15:             persistenceModel.UseOverridesFromAssembly(assembly);
  16:         }
  17:  
  18:         var connString = ConfigurationManager.ConnectionStrings[0].ConnectionString;
  19:  
  20:         var cfg = Fluently.Configure()
  21:             .Database(MySQLConfiguration.Standard.ConnectionString(connString)
  22:                           .Provider("NHibernate.Connection.DriverConnectionProvider, NHibernate")
  23:                           .Dialect("NHibernate.Dialect.MsSql2008Dialect")
  24:                           .Driver("NHibernate.Driver.SqlClientDriver")
  25:                           .ShowSql)
  26:             .CurrentSessionContext("NHibernate.Context.ThreadStaticSessionContext, NHibernate")
  27:             .Mappings(m =>
  28:                           {
  29:                               m.AutoMappings.Add(persistenceModel);
  30:                               foreach (var assembly in allAssemblies)
  31:                               {
  32:                                   m.FluentMappings.AddFromAssembly(assembly);
  33:                               }
  34:                           })
  35:             .BuildConfiguration();
  36:  
  37:         SessionFactoryMember = cfg.BuildSessionFactory();
  38:     }
  39:  
  40:     public static ISessionFactory SessionFactory
  41:     {
  42:         get { return SessionFactoryMember; }
  43:     }
  44: }
posted on Wednesday, April 18, 2012 9:25 AM