Tuesday, May 14, 2013

More Hibernation Fun :: Dialect does not support variable limits.


Had a sad-panda moment when I went to Linq to NHibernate with the following (rather straight-forward) syntax.

...

 var e = r.Where(w => w.Name.Contains(searchBy)).Select(c => c).Take(5).ToList();  
...
I bombed out on a simple test - with the exception being "Dialect does not support variable limits." Rather broad base of Google hits on this one...

Seemed like something wrong with the underlying dialect - so I needed to override; something like this:
 public class FixedMsSqlDialect : NHibernate.Dialect.MsSql2005Dialect  
   {  
     public override bool SupportsVariableLimit  
     {  
       get  
       {  
         return true; //because SQL Server DOES support TOP selects  
       }  
     }  
   }  

...


What was unclear was "where" does that go? Quick breeze through source revealed that it was 'set' right after the IPersistenceConfigurer was instantiated - so static method to use for my fluent configuration.
... 


 private static IPersistenceConfigurer PersistenceConfigurer(string connection)  
     {  
       var provider = MsSqlConfiguration.MsSql2005.ConnectionString(connection);  
       provider.Dialect<FixedMsSqlDialect>();  
       return provider;  
     }  
...

Now based on connection string - I can inject the "home-grown" default behavior from my GetConfiguration method.

...
 public FluentHelper(string connectionKey, bool autoConfig = false)  
       : this(  
         () =>  
         Fluently.Configure()  
         .Database(GetConfigurationOption(connectionKey))  
         .Mappings(m => m.FluentMappings.AddFromAssembly(Assembly.GetExecutingAssembly()))  
           .ExposeConfiguration((c =>  
           {  
             if (autoConfig)  
             {  
               BuildSchema(c);  
             }  
           })).BuildSessionFactory())  
     {  
     }  
 private static IPersistenceConfigurer GetConfigurationOption(string connectionKey)  
     {  
       string connection = ConfigurationManager.ConnectionStrings[connectionKey].ConnectionString;  
       switch (ConfigurationManager.ConnectionStrings[connectionKey].ProviderName)  
       {  
 ....omitted for brevity  
           default:  
             return PersistenceConfigurer(connection);  
       }  
 }  

Hurray - Linq Take() actually works now.



No comments: