2010-08-19 8 views
3

네이티브 쿼리를 사용하여 이전 질문에서이 문제를 이미 해결했지만. where 절을 사용하지 않고 Criteria에서 사용할 수있는 커스텀 표현식을 생성 할 수 있는지 궁금하다. where 절을 원하지 않는 이유는 오라클의 connect by ... start with ... (here) 문 때문입니다. 나는 내 시작을 얻으려면 this 페이지를 따라 갔다. 그러나 이것은 select * from foo where connect by start with ...where 절을 사용하지 않고 사용자 지정 식을 만들 수 있습니까?

과 같은 코드를 생성합니다. 여기에 제가 사용하고있는 것이 있습니다. 생성 된 것을 살펴보면 where 절을 제외한 정확한 문을 생성한다고 말할 수 있습니다.

public class StartWithConnectByCriteria : AbstractCriterion 
{ 
    public StartWithConnectByCriteria(string parentName, string parentValue, string childName) 
    { 
     ParentName = parentName; 
     ParentValue = parentValue; 
     ChildName = childName; 
    } 

    public string ParentName { get; set; } 
    public string ParentValue { get; set; } 
    public string ChildName { get; set; } 
    public IProjection P { get; set; } 

    public override IProjection[] GetProjections() 
    { 
     if(P != null) 
     { 
      return new IProjection[] {P}; 
     } 
     return null; 
    } 

    public override TypedValue[] GetTypedValues(ICriteria criteria, ICriteriaQuery criteriaQuery) 
    { 
     return 
      CriterionUtil.GetTypedValues(criteriaQuery, criteria, P, ParentName, ParentValue.ToString()); 
    } 

    public override SqlString ToSqlString(ICriteria criteria, ICriteriaQuery criteriaQuery, 
              IDictionary<string, IFilter> enabledFilters) 
    { 
     var sqlBuilder = new SqlStringBuilder(); 
     SqlString[] parentColumnNames = CriterionUtil.GetColumnNames(ParentName, 
                   P, criteriaQuery, 
                   criteria, enabledFilters); 
     SqlString parentColumnName = parentColumnNames[0]; 

     SqlString[] childColumnNames = CriterionUtil.GetColumnNames(ChildName, 
                P, criteriaQuery, 
                criteria, enabledFilters); 
     SqlString childColumnName = childColumnNames[0]; 

     criteriaQuery.AddUsedTypedValues(GetTypedValues(criteria, criteriaQuery)); 
     sqlBuilder 
      .Add("start with " + parentColumnName + " = '" + ParentValue + "'") 
      .Add(" connect by prior " + childColumnName + " = " + parentColumnName); 

     return sqlBuilder.ToSqlString(); 
    } 

    public override string ToString() 
    { 
     return ""; 
    } 
} 

나는 이것을 이와 같이 사용하고 있습니다.

StartWithConnectByCriteria criterion = 
    new StartWithConnectByCriteria(
     "parent", 
     "parent_value", 
     "child"); 

DetachedCriteria dc = DetachedCriteria.For<NormalUpstream>("nu") 
    .Add(criterion); 

는 나는이 (가) DetachedCriteria에서 .Add()하지만 100 % 확실 함께 할 수있는 느낌이 듭니다. 불행히도 커스텀 표현식을 만드는 것에 대한 많은 문서를 찾을 수없는 것 같습니다.

편집 : 지금 내가 잘못된 트리를 짖고있는 것처럼 보입니다. 이것이 중요한 것은 아니지만 (이미 괜찮은 구현이 있음). 난 아직도 NHibernate를 더 커스터마이징 할 수있는 방법을 보는데 관심이있다.

편집 2 : 기본적으로 NHibernate는 오라클의 독점 기능인 start with ... connect by을 지원하지 않습니다. NHibernate에 대한 네이티브 지원을 추가하여 확장에 대해 자세히 배우려고합니다. 나는 그 기능을 사용자 정의 방언으로 등록 할 수 있다는 것을 알고 있습니다. 하지만 다른 기준 쿼리와 함께 사용할 수 있도록 기준으로 구현할 수 있는지 궁금합니다. 내가 게시 된 코드를 잘 작동하고 올바른 SQL을 만듭니다 있지만 StartWithConnectByCriteria 내 기준에 추가 할 때 NHibernate select this_.id from table where start with ... connect by 같은 쿼리를 발급합니다. 해당 절이 where에 속하지 않으므로 잘못된 쿼리입니다.

이것은 NHibernate가 생성 할 것으로 기대하는 쿼리입니다.

select 
    random_column 
from 
    table 
start with parent_id = 'parent_node_id' 
connect by prior child_up_id = parent_id 

이 쿼리에는 where 절이 없습니다. 그러나 start with ... connect by은 여전히 ​​where clause과 함께 사용할 수 있습니다. 해당 키워드의 작동 방식에 대한 자세한 내용은 here을 참조하십시오.

답변

0

기존의 NHibernate 구문이이를 허용하는지는 모르지만, 유용 할 수도있는 계층 적 쿼리를위한 ANSI 표준 구문이 있습니다. 나는 그것이 11R2 이상에서만 작동한다고 믿습니다. 그래서 그것이 당신에게 유익한 지 확신하지 못합니다. 자세한 내용은 Recursive Subquery Refactoring을 참조하십시오.

+0

기준 API가 'WITH'를 지원하지 않는다고 생각합니다. HQL이나 네이티브 SQL 쿼리를 사용하여 우리와 함께 떠날 수도 있습니다. 고맙습니다. – Mike

관련 문제