2009-12-02 4 views
1

FormCollection에서 검색 조건의 존재 여부를 확인하는 저장소에 기존 고급 검색 방법이 있으며, 검색 기준에 검색 기준이 추가되어 있습니다.NHibernate 및 SQL Server Geography를 사용하여 거리가있는 고급 검색

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>(); 
} 

나는 또한 각 거주지가 검색 기준에서 얼마나 먼지 찾기 위해 기본적인 거리 검색을 가지고있다.

CREATE FUNCTION dbo.GetDistance 
(
    @firstPoint nvarchar(100), 
    @secondPoint GEOMETRY 
) 
RETURNS float 
AS 
BEGIN 
    RETURN GEOGRAPHY::STGeomFromText(
    @firstPoint, 4326).STDistance(@secondPoint.STAsText())/1609.344 
END 

그리고 : 쿼리에 대한 HBM은 NHibernate에이 지역 함수에서 콜론을 탈출 갈 수있는 방법이 없었습니다 나는이 거리를 계산하는 함수를 정의했다

<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> 

입니다 저장소 따라서 명명 된 쿼리를 호출합니다 :

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.IsWithinDistanceSystem.NotImplementedException를 반환했습니다.

답변

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)); 

UPDATE

nb 내가 게시했을 때 이것이 효과가 있었음에도 불구하고 더 이상 작동하지 않습니다. NHibernate는 '.'을 좋아하지 않는다. dbo 후,

"dbo : Residences.Domain.Residence"속성을 확인할 수 없습니다.

'dbo.' 내가 얻을

" 'GetDistance'는 인식 할 수없는 기본 제공 함수 이름이 아닙니다."

0

NHibernate.Spatial project을 보았습니까? 이렇게하면 문제를 쉽게 해결할 수 있습니다.

대안은 ICriterion의 고유 한 구현을 만드는 것입니다. AbstractCriterion에서 파생되어 특정 데이터베이스 플랫폼을 타겟팅하면 너무 까다로운 문제는 아닙니다. 그러면 거리 함수를 다른 기준과 결합 할 수 있습니다.

+0

감사합니다. 존, 사용하고 있지만 작동시키지 못했습니다. IsWithinDistance가 구현되지 않은 것으로 보입니다. 나는 너의 두 번째 제안을 해줄거야. – harriyott