In my previous NH Spatial post I've shown a concrete end-to-end example of how to use NHibernate Spatial on an ASP.NET MVC project.
Anyway, there's still much to be said about using this library and I've received some hits on my blog from people who were searching for how to do specific spatial operations with NH Spatial. So, this blog post will be pretty much practical, showing some spatial queries using NH Spatial on SQL Server 2008 R2, taking into account some variables in the process:
- Geography (always assuming SRID 4326) and Geometry data types
- HQL and LINQ
- NHibernate version
But first, regarding NHibernate version, the current "official" release is 220.127.116.1100. Unfortunately NHibernate Spatial does not compile with it. I've fixed those compilation errors locally (pretty simple) but it's not enough. Some of the spatial operations don't register the Sql parameters correctly and I believe it's a bug in NHibernate. I've narrowed it down to the NHibernate.Loader class, but haven't invested much trying to solve it. So, for the sake of this post, I'm going to use NHibernate 18.104.22.16800 (which was also the version that I've used in my previous post). Anyway, if you expect to deal mostly with HQL you can risk the 22.214.171.12400 version, as the problem I described is mostly related with QueryOver and LINQ.
Regarding the session object, in one of my previous posts I've shown how to create a valid session factory for spatial operations in SQL Server. I'll show examples for both geometry and geography. Typically one will not mix geometries and geographies in the same application.
Fluently.Configure() .Database( MsSqlConfiguration.MsSql2008 .ConnectionString("<connection string>") .Dialect<MsSql2008GeometryDialect>()) .Mappings(m => m.FluentMappings.AddFromAssemblyOf<DistrictMap>()) .BuildSessionFactory();geography:
Fluently.Configure() .Database( MsSqlConfiguration.MsSql2008 .ConnectionString("<connection string>") .Dialect<MsSql2008GeographyDialect>()) .Mappings(m => m.FluentMappings.AddFromAssemblyOf<DistrictMap>()) .BuildSessionFactory();Also, and assuming Fluent NHibernate for the mappings, map each property according to their custom type.
Map(x => x.AreaWithGeography).CustomType<MsSql2008GeometryType>();
Map(x => x.AreaWithGeography).CustomType<Wgs84GeographyType>();The Wgs84GeographyType class was created by me in one of my previous posts so that the mappings could be done by code using FluentNHibernate. Otherwise we would have to use XML mappings to set the correct SRID.
Now, let's start querying:
Enough for now. I'll probably pick the NHibernate Spatial topic in another post.
If I manage to find some time I'll try to contact Ricardo Stuven so that I may commit some of the corrections and improvements that I've implemented locally. NHibernate Spatial is a great project, and it's a pity that it hasn't got much attention lately from its developers.