I've got an existing advanced search method in a repository that checks a FormCollection
for the existence of search criteria, and if present, adds a criterion to the search e.g.
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>();
}
I've also got a basic distance search to find how far each residence is from the search criteria. The HBM for the query is
<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>
I had to define a function to calculate the distance, as there was no way to get NHibernate to escape the colons in the geography function:
CREATE FUNCTION dbo.GetDistance
(
@firstPoint nvarchar(100),
@secondPoint GEOMETRY
)
RETURNS float
AS
BEGIN
RETURN GEOGRAPHY::STGeomFromText(
@firstPoint, 4326).STDistance(@secondPoint.STAsText()) / 1609.344
END
And the repository calls the named query thus:
return Session.GetNamedQuery("Residence.Nearest")
.SetString("point", String.Format("POINT({0} {1})", latitude, longitude)) .List();
So my question is; how do I combine the two (or start from scratch), so I can filter the advanced search results to include only residences within 10 miles of the search location?
UPDATE I have tried using NHibernate.Spatial with the following code:
criteria.Add(SpatialExpression.IsWithinDistance(
"Coordinate", new Coordinate(latitude, longitude), 10));
but SpatialExpression.IsWithinDistance
returned a System.NotImplementedException
.