NHibernate.Spatial和SQL 2008地理类型 - 如何配置(NHibernate.

2019-07-20 03:01发布

我试图使用NHibernate的与SQL 2008地理类型和时遇到困难。 我用流利的NHibernate的配置,我是相当新的,这样可能是这个问题为好。

首先,我想坚持的类看起来是这样的:

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;}
}

映射类是这样的:

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

为了使用与功能NHibernate的MsSql2008GeographyDialect,我已经创建了自己的配置类:

public class Sql2008Configuration
  : PersistenceConfiguration<Sql2008Configuration, MsSqlConnectionStringBuilder>
{
   public Sql2008Configuration()
   {
      Driver<SqlClientDriver>();
   }

   public static Sql2008Configuration MsSql2008
   {
      get { return new Sql2008Configuration().Dialect<MsSql2008GeographyDialect>(); }
   }
}

所以我必须配置这样的代码:

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

所有这些设置的事实,我正在努力坚持的LocationLog型数据库的时候出现以下错误:

System.ArgumentException:24204:用户定义的例程或聚合“地理”执行过程中出现一个.NET Framework错误的空间参考标识符(SRID)是无效的。 指定的SRID必须匹配在sys.spatial_reference_systems目录视图中显示的支撑SRIDs之一。 System.ArgumentException:在Microsoft.SqlServer.Types.SqlGeography.set_Srid在Microsoft.SqlServer.Types.SqlGeography.Read(BinaryReader在r)是SqlGeography(的Int32值):: DeserializeValidate(IntPtr的,的Int32,CClrLobContext *)

我已阅读有关如何配置和使用NHibernate的空间库下面的文章:

  • http://nhibernate.info/doc/spatial/configuration-and-mapping.html
  • http://nhibernate.info/doc/spatial/sample-usage.html

但也没什么帮助。 有经验配置NHibernate的使用空间地理类型谁可以提供任何见解任何人将不胜感激。

Answer 1:

我在同一条船上,并感谢您的开始我得到它的工作(插入和阅读空间数据)。 对于任何人谁是有兴趣,首先GisSharpBlog.NetTopologySuite.Geometries.Point类是在NetTopologySuite.dll这是nHibernate.Spatial下载的一部分。

其次,按照詹姆斯点,请确保您的SRID设置为4326。

最后,地图需要看起来像这样:

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

我使用的地理,但我读的地方,使用GeometryType可以工作,它为我(我插入一些点,并在数据库中验证的话)。 我也看了,它的最好写SQL查询对地理,这样就可以使用特殊的SQL 2008空间的方法(而不是使用标准)。



Answer 2:

史蒂夫是正确的,你需要明确设置SRID为您的几何类型。 纵观NHibernate.Spatial源(你可以检出使用任何SVN或),做着SRID搜索这个埋藏在代码中的注释提示出现:

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

它看起来像你需要设置一个名为参数SRID到你需要的任何数(看它在SRID表)。 显然,这是老派的XML配置,但是流利将有一个方法某处添加键/值字符串参数。 给一个尝试。


编辑

更多的研究,我发现,试图设置在列SRID属性失败NHibernate的XML映射验证,它抛出一个XmlSchemaValidationException。 相反,我发现在NetNopologySuite是几何类型有对象本身上SRID属性,设置这使得事情的工作。 例如

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

必须有一个更好的方式来做到这一点,虽然(它配置,而不是设置它所有的时间),但我还没有制定了这一点呢。 如果你看MsSql2008GeometryType类里面,它有一个叫做SetDefaultSRID(IGeometry)受保护的方法 - 那一定是有原因的!



Answer 3:

不是一个真正的答案,但问题;-)

  • 你设置GisSharpBlog.NetTopologySuite.Geometries.Point对象的SRID?

默认的(因为点是几何形状)为0,并试图坚持的LocationLog.Location属性作为一个地理学的时候会给你一个SQL错误。 0不是SQL地理学领域的一个有效的SRID。 你需要指定一个来自sys.spatial_reference_systems视图。

  • 你有没有试过不连贯NHibernate?

为了消除该问题,因为许多组件。



Answer 4:

你可以创建自己的工厂有一个默认的SRID。 例如,您可以创建一个工厂,如这一个门面:

public static class Default
{
    private const int DefaultSrid = 4326;

    public static readonly IGeometryFactory Factory;

    static Default()
    {
        Factory = new GeometryFactory(new PrecisionModel(), DefaultSrid);
    }
}

并使用它像这样:

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

而是采用了“新”的关键字。 您也可以使用Default.Factory作为工厂方法在你的IoC框架没有默认门面创造新的几何形状。



Answer 5:

我知道这几乎是有用的,但在任何情况下。 实现所有LAIN说过不要在你的HQL使用后查询的setParameter第三ITYPE参数。 在含义

 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();

新CustomType(typeof运算(MsSql2008GeographyType),空)必须通过或你得到你太famililar “System.ArgumentException:24204”。

只花了一整夜盘算,一个出。



文章来源: NHibernate.Spatial and Sql 2008 Geography type - How to configure