我有一个存储库中的现有高级搜索方法,检查FormCollection
是否存在搜索条件,如果存在,则向搜索添加条件。使用NHibernate和SQL Server地理高级搜索距离
public IList<Residence> GetForAdvancedSearch(FormCollection collection)
{
var criteria = Session.CreateCriteria(typeof(Residence))
.SetResultTransformer(new DistinctRootEntityResultTransformer());
if (collection["MinBedrooms"] != null)
{
criteria
.Add(Restrictions.Ge("Bedrooms", int.Parse(collection["MinBedrooms"])));
}
// ... many criteria omitted for brevity
return criteria.List<Residence>();
}
我也有一个基本的距离搜索,以找到每个住所离搜索标准有多远。用于查询的HBM是
<sql-query name="Residence.Nearest">
<return alias="residence" class="Residences.Domain.Residence, Residences"/>
<return-scalar column="Distance" type="float"/>
SELECT R.*, dbo.GetDistance(:point, R.Coordinate) AS Distance
FROM Residence R
WHERE Distance < 10
ORDER BY Distance
</sql-query>
我必须定义一个函数来计算距离,因为没有办法让NHibernate的逃避地理功能冒号:
CREATE FUNCTION dbo.GetDistance
(
@firstPoint nvarchar(100),
@secondPoint GEOMETRY
)
RETURNS float
AS
BEGIN
RETURN GEOGRAPHY::STGeomFromText(
@firstPoint, 4326).STDistance(@secondPoint.STAsText())/1609.344
END
而存储库调用这个命名查询:
return Session
.GetNamedQuery("Residence.Nearest")
.SetString("point", String.Format("POINT({0} {1})", latitude, longitude))
.List();
所以我的问题是;我如何将两者结合起来(或从头开始),因此我可以将高级搜索结果过滤为仅包含搜索位置10英里内的住宅?
UPDATE我一直在使用NHibernate.Spatial用下面的代码尝试:
criteria.Add(SpatialExpression.IsWithinDistance(
"Coordinate", new Coordinate(latitude, longitude), 10));
但SpatialExpression.IsWithinDistance
返回System.NotImplementedException
。
谢谢约翰,我一直在使用它,但一直未能得到它的工作。 IsWithinDistance似乎没有被执行。我会提出你的第二个建议。 – harriyott 2009-12-03 00:48:44