2013-05-08 101 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

如果您不想額外添加一列,您可以創建一個視圖,該視圖將使用函數從原始表中提取數據,並在視圖上創建一個而不是觸發器來更新實際表。