0

我需要使用 nHibernate 将 postgis 几何列作为 wkt 读取。我知道我可以使用 nHibernate Spatial,但这不是我的选择。

我看过这篇文章:Best way to map a hidden property in NHibernate (fluent) where wkt is stored in another column and he uses triggers to update the actual geometry. 但是,项目所有者不希望为此添加额外的列。

我也发现了这个线程:Use PostGIS columns transparent in Hibernate,但没​​有提供答案。

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

谢谢!

4

2 回答 2

0

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

于 2013-05-08T19:22:27.470 回答
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;   
    }
于 2013-05-15T06:53:17.157 回答