我通过使用 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;
}