我试图使用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的使用空间地理类型谁可以提供任何见解任何人将不胜感激。
我在同一条船上,并感谢您的开始我得到它的工作(插入和阅读空间数据)。 对于任何人谁是有兴趣,首先GisSharpBlog.NetTopologySuite.Geometries.Point类是在NetTopologySuite.dll这是nHibernate.Spatial下载的一部分。
其次,按照詹姆斯点,请确保您的SRID设置为4326。
最后,地图需要看起来像这样:
Map(a => a.Location).CustomType(typeof(NHibernate.Spatial.Type.GeometryType));
我使用的地理,但我读的地方,使用GeometryType可以工作,它为我(我插入一些点,并在数据库中验证的话)。 我也看了,它的最好写SQL查询对地理,这样就可以使用特殊的SQL 2008空间的方法(而不是使用标准)。
史蒂夫是正确的,你需要明确设置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)受保护的方法 - 那一定是有原因的!
不是一个真正的答案,但问题;-)
- 你设置GisSharpBlog.NetTopologySuite.Geometries.Point对象的SRID?
默认的(因为点是几何形状)为0,并试图坚持的LocationLog.Location属性作为一个地理学的时候会给你一个SQL错误。 0不是SQL地理学领域的一个有效的SRID。 你需要指定一个来自sys.spatial_reference_systems视图。
为了消除该问题,因为许多组件。
你可以创建自己的工厂有一个默认的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框架没有默认门面创造新的几何形状。
我知道这几乎是有用的,但在任何情况下。 实现所有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”。
只花了一整夜盘算,一个出。