我在存储库中有一个现有的高级搜索方法,用于检查FormCollection
是否存在搜索条件,如果存在,则为搜索添加一个标准,例如。
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英里范围内的住宅?
更新我尝试使用NHibernate.Spatial并使用以下代码:
criteria.Add(SpatialExpression.IsWithinDistance(
"Coordinate", new Coordinate(latitude, longitude), 10));
但SpatialExpression.IsWithinDistance
返回了System.NotImplementedException
。
答案 0 :(得分:0)
你见过NHibernate.Spatial project吗?这可以为您的问题提供简单的解决方案。
另一种方法是创建自己的ICriterion
实现 - 如果从AbstractCriterion
派生并且您定位特定的数据库平台,这不是太棘手。这样就可以将距离函数与其他标准结合起来。
答案 1 :(得分:0)
创建一个投影,实际上是为结果添加一个新的距离列,通过调用UDF计算,然后为其添加一个限制:
var query = String.Format(
"dbo.GetDistance('POINT({0} {1}', Coordinate) AS Distance",
latitude, longitude);
criteria
.Add(Restrictions.Le(Projections.SqlProjection(
query,
new [] {"Distance"},
new [] {NHibernateUtil.Double}), 10));
<强>更新强>
n.b。虽然这一点在我发布时一定有用,但它不再起作用了。 NHibernate不喜欢'。'在dbo之后,并说
“无法解析财产:dbo of:Residences.Domain.Residence”。
如果我删除'dbo'。我得到了
“'GetDistance'不是公认的内置函数名称。”