我需要使用nHibernate读取postgis几何列作为wkt。我知道我可以使用nHibernate Spatial,但在我的情况下这不是一个选项。
我看过这篇文章:Best way to map a hidden property in NHibernate (fluent)其中wkt存储在另一列中,他使用触发器来更新实际的几何体。但是,项目所有者不希望为此目的添加额外的列。
我也找到了这个帖子:Use PostGIS columns transparently in Hibernate,但没有提供答案。
我相信我需要写一个自定义类型,但我真的需要有人指出我正确的方向。我之前没有使用过Postgresql / postgis。
日Thnx!
答案 0 :(得分:0)
如果您不想要额外的列,您可以创建一个视图,该视图将使用函数从原始表中提取数据,并在视图上创建一个而不是触发器来更新真实表。
答案 1 :(得分:0)
我通过使用nHibernates sql-interceptor解决了这个问题。不是最强大的解决方案,但这样我可以为PostGis和Oracle提供不同的拦截器。
我还研究了nHibernate.Spatial及其几何类型。但我不想使用NetTopologySuite,因此我应该需要编写更多代码。
以下是代码的一部分:
public class PostGisGeometrySqlInterceptor : IInterceptor
{
...
/// <summary>
/// Modifies all the select statements with geometry so that
/// xxx.geometry -> ST_AsText(xxx.geometry)
/// </summary>
/// <param name="sql">The original sql string.</param>
/// <returns>The modified sql string.</returns>
/// <remarks>
/// All the geometry fields must be called 'geometry'.
/// Works only for one geometry in the sql string.
/// </remarks>
public virtual SqlString OnPrepareStatement(SqlString sql)
{
if (sql.StartsWithCaseInsensitive("SELECT") && sql.ToString().Contains("geometry"))
{
var indexOfGeometry = sql.IndexOfCaseInsensitive("geometry");
var indexOfSpace = sql.Substring(0, indexOfGeometry).LastIndexOfCaseInsensitive(" ") + 1;
var oldValue = sql.ToString(indexOfSpace, indexOfGeometry - indexOfSpace + "geometry".Length);
var newValue = string.Format("ST_AsText({0})", oldValue);
sql = sql.Replace(oldValue, newValue);
}
else if(...)
...
return sql;
}