2013-05-08 66 views
0

我需要使用nHibernate阅读postgis几何列作为wkt。我知道我可以使用nHibernate Spatial,但这不是我的选择。如何映射PostGis几何列作为与nHibernate不使用nHibernate空间

我看到这篇文章:Best way to map a hidden property in NHibernate (fluent)其中wkt存储在另一列,他使用触发器来更新实际几何。但项目业主不希望为此增加额外的专栏。

我发现这个主题以及:Use PostGIS columns transparently in Hibernate,但没有提供了一个答案。

我相信我需要写一个自定义类型,但我真的需要有人指点我正确的方向。我之前没有使用Postgresql/postgis。

Thnx!

回答

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

如果您不想额外添加一列,您可以创建一个视图,该视图将使用函数从原始表中提取数据,并在视图上创建一个而不是触发器来更新实际表。