Feed Subscribe
Exception has been thrown by the target of an invocation.

N2CMS, NHibernate, SqlCommandSet and medium trust

by ondrejsv 15. May 2011 13:14

Recently I installed the current version of the N2CMS to power my personal homepage. I’m running on shared webhosting so you may imagine how poor performance is. To speed up the thing a little I decided to switch from SqlCe database to the full blown SQL Server.

However, after changing the connection string the N2CMS does not even install itself:

Attempt by method 'NHibernate.AdoNet.SqlClientSqlCommandSet..ctor()' to access method 'System.Data.SqlClient.SqlCommandSet..ctor()' failed.

If you carefully look at the source code of the NHibernate.AdoNet.SqlClientSqlCommandSet, you will discover the ugly reflection:

/// /// Expose the batch functionality in ADO.Net 2.0 /// Microsoft in its wisdom decided to make my life hard and mark it internal. /// Through the use of Reflection and some delegates magic, I opened up the functionality. /// /// Observable performance benefits are 50%+ when used, so it is really worth it. /// public class SqlClientSqlCommandSet ...
static SqlClientSqlCommandSet() { Assembly sysData = Assembly.Load("System.Data, Version=, Culture=neutral, PublicKeyToken=b77a5c561934e089"); sqlCmdSetType = sysData.GetType("System.Data.SqlClient.SqlCommandSet"); Debug.Assert(sqlCmdSetType != null, "Could not find SqlCommandSet!"); }

To continue installing, either make the reflection work by switching your application to full trust (provided your hosting company will allow this):

or disable NHibernate batching feature (and you will lose “observable performance benefirst 50%+” as the author of the NHibernate comment claims Smile) by following the commit message:

Enabling batching is done by defining (the new) property "hibernate.batch_size" to a size greater than zero. This way require an explicit action to enable it, but this is probably a good thing.

Tags: , ,

NHibernate lowercase and underscore automap convention

by ondrejsv 20. February 2011 00:26

Today just a small snippet of code. If you unlucky one inherited some brownfield database with awkward lowercase_and_underscores naming convention (I really hate it):


and you are using NHibernate with Fluent automapping configuration, just use this property convention:

private class ColumnConvention : IPropertyConvention { public void Apply(FluentNHibernate.Conventions.Instances.IPropertyInstance instance) { var regexString = @"([A-Z][\w^[A-Z]]*)([A-Z][\w^[A-Z]]*)*"; var newName = Regex.Replace(instance.Name, regexString, (m => (m.Index != 0 ? "_" : "") + m.Value.ToLower())); instance.Column(newName); } }

Of course, the real gem here is the regex itself (days without writing regexes are awesome).

If you forgot how to apply a custom convention, here you go:

SessionFactory = Fluently.Configure().Database( MsSqlConfiguration.MsSql2008.ConnectionString(c => c.FromConnectionStringWithKey("SugarCrmDb"))). Mappings( m => m.AutoMappings.Add(AutoMap. AssemblyOf(cfg). Override(am => am.Table("accounts")). Conventions.Add(new ColumnConvention()) ) ). BuildSessionFactory();
If you really don’t know what is this all about, take a read here.