visual tutorial studio framework example español descargar c# nhibernate sql-server-2008 fluent-nhibernate geography

c# - tutorial - Tipo de geografía NHibernate.Spatial y Sql 2008-Cómo configurar



nhibernate visual studio 2017 (5)

Estoy tratando de usar Nhibernate con el tipo de Geografía Sql 2008 y estoy teniendo dificultades. Estoy usando Fluent Nhibernate para configurar a lo que soy bastante nuevo, de modo que ese también puede ser el problema.

Primero, la clase que estoy tratando de persistir se ve algo así como:

public class LocationLog : FluentNHibernate.Data.Entity { public virtual new int Id {get;set;} public virtual DateTime TimeStamp {get;set;} public virtual GisSharpBlog.NetTopologySuite.Geometries.Point Location {get;set;} }

La clase de mapeo se ve así:

public class LocationLogMap : ClassMap<LocationLog> { ImportType<GisSharpBlog.NetTopologySuite.Geometries.Point>(); Id(x => x.Id); Map(x => x.TimeStamp).Generated.Insert(); Map(x => x.Location); }

Para utilizar MsSql2008GeographyDialect with Fluent Nhibernate, he creado mi propia clase de configuración:

public class Sql2008Configuration : PersistenceConfiguration<Sql2008Configuration, MsSqlConnectionStringBuilder> { public Sql2008Configuration() { Driver<SqlClientDriver>(); } public static Sql2008Configuration MsSql2008 { get { return new Sql2008Configuration().Dialect<MsSql2008GeographyDialect>(); } } }

Así que tengo el código de configuración como:

var configuration = Fluently.Configure() .Database(Sql2008Configuration.MsSql2008.ConnectionString(c => c.Is(connectionString))) .Mappings(m => m.FluentMappings .AddFromAssemblyOf<LocationLog>() );

Todo esto para configurar el hecho de que obtengo el siguiente error al intentar conservar el tipo de registro de ubicación en la base de datos:

Se produjo un error de .NET Framework durante la ejecución de la "geografía" definida por el usuario o agregada: System.ArgumentException: 24204: el identificador de referencia espacial (SRID) no es válido. El SRID especificado debe coincidir con uno de los SRID compatibles que se muestran en la vista de catálogo sys.spatial_reference_systems. System.ArgumentException: en Microsoft.SqlServer.Types.SqlGeography.set_Srid (valor de Int32) en Microsoft.SqlServer.Types.SqlGeography.Read (BinaryReader r) en las partes de la piscina (Intptr.)

He leído los siguientes artículos sobre cómo configurar y usar las bibliotecas de Nhibernate Spatial:

pero ninguno parece ayudar. Cualquier persona que tenga experiencia en la configuración de Nhibernate para usar los tipos de Geografía espacial que puedan proporcionar cualquier información sería muy apreciada.


Estoy en el mismo barco y, gracias a su inicio, lo puse en funcionamiento (insertando y leyendo datos espaciales). Para cualquier persona interesada, en primer lugar, la clase GisSharpBlog.NetTopologySuite.Geometries.Point está en NetTopologySuite.dll, que forma parte de la descarga de nHibernate.Spatial.

En segundo lugar, según el punto de James, asegúrese de establecer el SRID en 4326.

Y por último, el mapa debe verse así:

Map(a => a.Location).CustomType(typeof(NHibernate.Spatial.Type.GeometryType));

Estoy usando Geografía, pero leí en alguna parte que usar GeometryType puede funcionar y lo hace por mí (inserté algunos puntos y lo verifiqué en la base de datos). También leí que es mejor escribir SQL Query''s para Geografía para que pueda usar los métodos especiales de SQL 2008 Spatial (en lugar de usar Criterios).


No es realmente una respuesta sino preguntas ;-)

  • ¿Está configurando un SRID en el objeto GisSharpBlog.NetTopologySuite.Geometries.Point ?

El valor predeterminado (dado que el punto es una geometría) es 0 y le dará un error de SQL al intentar conservar la propiedad LocationLog.Location como una geografía. 0 no es un SRID válido para campos de geografía SQL. Deberá especificar uno desde la vista sys.spatial_reference_systems.

  • ¿Has probado sin Fluido NHibernate?

Para eliminar tantos componentes del problema.


Puede crear su propia fábrica con un SRID predeterminado. Por ejemplo, puede crear una fachada para fábricas como esta:

public static class Default { private const int DefaultSrid = 4326; public static readonly IGeometryFactory Factory; static Default() { Factory = new GeometryFactory(new PrecisionModel(), DefaultSrid); } }

y úsalo así:

var point = Default.Factory.CreatePoint(new Coordinate(10, 10));

en lugar de utilizar la palabra clave "nueva". También puede usar la fábrica Default.Factory como un método de fábrica en su marco de IoC para crear nuevas geometrías sin la fachada predeterminada.


Sé que esto no será útil pero en cualquier caso. Después de implementar todo lo que se había dicho, use en sus consultas HQL el tercer parámetro IType de SetParameter. Significado en

Hero hero = openSession.Get<Hero>(3); openSession.CreateQuery( "from Hero h where NHSP.Distance(h.Location,:thislocation)<1000" ).SetParameter("thislocation", hero.Location, new CustomType(typeof(MsSql2008GeographyType), null) ).SetResultTransformer(new DistinctRootEntityResultTransformer()) .List();

se debe pasar el nuevo CustomType (typeof (MsSql2008GeographyType), null) o obtendrá su "System.ArgumentException: 24204" demasiado familiar.

Acabo de pasar toda la noche pensando en eso.


Steve tiene razón, debe establecer explícitamente un SRID para su tipo de geometría. En cuanto a la fuente de NHibernate.Spatial (que puede realizar el checkout con SVN o lo que sea), al realizar una búsqueda de SRID aparece esto incluido en el código como una sugerencia de comentario:

<class name="MyGeoTableA"> <property name="MyGeoColumn"> <type name="NHibernate.Spatial.Type.GeometryType, NHibernate.Spatial"> <param name="srid">1234</param> </type> </property> </class>

Parece que necesita establecer un parámetro llamado SRID en el número que necesite (búsquelo en una tabla SRID). Obviamente, esta es la configuración XML de la vieja escuela, pero fluida tendrá un método en algún lugar para agregar parámetros de cadena de clave / valor. Dale una oportunidad a eso.

Editar

Después de un poco más de investigación, descubrí que al intentar establecer un atributo srid en una columna, la validación de la asignación de XML de NHibernate no se realizó correctamente, se genera una XmlSchemaValidationException. En su lugar, descubrí que los tipos de geometría en NetNopologySuite tienen un atributo SRID en el objeto en sí, y la configuración hace que las cosas funcionen. p.ej

LocationLog log = new LocationLog { Location = new Point() }; log.Location.SRID = 4326; Session.Save(log);

Sin embargo, debe haber una mejor manera de hacerlo (configúrelo en lugar de configurarlo todo el tiempo) pero aún no lo he resuelto. Si mira dentro de la clase MsSql2008GeometryType, tiene un método protegido llamado SetDefaultSRID (IGeometry) - ¡debe estar ahí por una razón!