2009-05-08 6 views
0

기본 키와 정렬 순서가 주어진 NHibernate 쿼리에서 "주변"행을 검색하는 방법을 찾고 있습니까?NHibernate 쿼리에서 "주변"행 가져 오기

예. 로그 엔트리가있는 테이블이 있는데 기본 키 4242와 이전 5 개 항목 및 다음 5 개 항목을 날짜별로 정렬하여 표시하려고합니다 (날짜와 기본 키 사이에는 직접적인 관계가 없습니다). 이러한 쿼리는 총 11 개의 행을 반환해야합니다 (한 쪽 끝에 가까이 있지 않은 경우).

로그 엔트리 테이블은 거대 할 수 있으며 알아 내기 위해 모든 것을 검색 할 수 없습니다.

NHibernate에서 사용할 수있는 행 번호와 같은 개념이 있습니까? 기본 데이터베이스는 SQlite 또는 Microsoft SQL Server 중 하나입니다.

Id Time 
4237 10:00 
4238 10:00 
1236 10:01 
1237 10:01 
1238 10:02 
4239 10:03 
4240 10:04 
4241 10:04 
4242 10:04 <-- requested "center" row 
4243 10:04 
4244 10:05 
4245 10:06 
4246 10:07 
4247 10:08 

우리가 1237, 1238 및 4239 4247. 순서로 행을 받아야 기본 키 (4242)와 함께 입장을 요청하는 경우 :

편집 추가 샘플

는 다음과 같은 데이터를 상상 시간이지, 이드.

단일 쿼리 (분명히 하위 쿼리를 포함 할 수 있음)에서 항목을 검색 할 수 있습니까? 시간은 고유하지 않은 열이므로 여러 항목의 값이 같고이 예에서는 고유하게 만드는 방식으로 해상도를 변경할 수 없습니다!

답변

1

"날짜와 기본 키간에 직접적인 관계가 없음"은 기본 키가 순차적 순서가 아님을 의미합니까?

그럼 이런 식으로 할 것 : 동시에 여러 항목을 가지고있는 위험이 있습니다

Item middleItem = Session.Get(id); 

IList<Item> previousFiveItems = Session.CreateCriteria((typeof(Item)) 
    .Add(Expression.Le("Time", middleItem.Time)) 
    .AddOrder(Order.Desc("Time")) 
    .SetMaxResults(5); 

IList<Item> nextFiveItems = Session.CreateCriteria((typeof(Item)) 
    .Add(Expression.Gt("Time", middleItem.Time)) 
    .AddOrder(Order.Asc("Time")) 
    .SetMaxResults(5); 

.


편집

이 이제 작동합니다.

Item middleItem = Session.Get(id); 

IList<Item> previousFiveItems = Session.CreateCriteria((typeof(Item)) 
    .Add(Expression.Le("Time", middleItem.Time)) // less or equal 
    .Add(Expression.Not(Expression.IdEq(middleItem.id))) // but not the middle 
    .AddOrder(Order.Desc("Time")) 
    .SetMaxResults(5); 

IList<Item> nextFiveItems = Session.CreateCriteria((typeof(Item)) 
    .Add(Expression.Gt("Time", middleItem.Time)) // greater 
    .AddOrder(Order.Asc("Time")) 
    .SetMaxResults(5); 
+0

로 광고 작동합니다. 서로 다른 열을 정렬해야하므로 시퀀스 열을 유지하는 것이 효과가 없을 수 있습니다. 고유하지 않은 열을 정렬해야하는 상황에서 rownum 솔루션을 찾고 있었기 때문에 더 많은 아이디어가 환영받을만한 것이 었습니다 .-) – HakonB

+0

좋습니다. 새로운 섹션을 참조하십시오. –

0

이 NHibernate에의 기준 API 비교적 용이해야한다 : 여기

List<LogEntry> logEntries = session.CreateCriteria(typeof(LogEntry)) 
.Add(Expression.InG<int>(Projections.Property("Id"), listOfIds)) 
.AddOrder(Order.Desc("EntryDate")) 
.List<LogEntry>(); 

당신의 listOfIds 당신이 검색 할 항목의 ID를 나타내는 정수 (정수 4242-5의 강력한 형식의 목록은 그냥 ~ 4242 + 5).

물론 4232-5보다 크고 4242 + 5보다 작은 ID를 검색 할 수 있도록 Expressions을 추가 할 수도 있습니다.

+1

나는 어떻게 명성을 얻습니까? :) 5 분 안에 답을 올렸을 때 누군가 다른 사람도 올렸습니다. –

+0

그것은 돈이있는 그대로입니다. 당신이 그것을 가지고 있다면, 당신은 그것을 얻습니다. 사람들은 높은 평판을 가진 회원들의 답변에 대해 더 자주 투표합니다. 삶은 공정하지 않다. 그러나 상관하지 말고, 좋은 대답을 제공하는 것이 항상 중요하며 주된 의도가되어야합니다. –

+0

Stefan이 위에서 언급했듯이 날짜와 기본 키 간에는 직접적인 관계가 없으므로 기본 키로 선택하는 것만으로는 효과가 없습니다. 기본 키 솔루션을 무효화하는 카테고리별로 필터링해야하는 솔루션이있을 수도 있습니다. – HakonB

0

스테판의 솔루션은 분명하지만 더 좋은 방법이 하나의 선택과 중첩 된 하위 쿼리를 사용하여 존재 작동합니다

ICriteria crit = NHibernateSession.CreateCriteria(typeof(Item)); 

     DetachedCriteria dcMiddleTime = 
      DetachedCriteria.For(typeof(Item)).SetProjection(Property.ForName("Time")) 
      .Add(Restrictions.Eq("Id", id)); 

     DetachedCriteria dcAfterTime = 
      DetachedCriteria.For(typeof(Item)).SetMaxResults(5).SetProjection(Property.ForName("Id")) 
      .Add(Subqueries.PropertyGt("Time", dcMiddleTime)); 
     DetachedCriteria dcBeforeTime = 
      DetachedCriteria.For(typeof(Item)).SetMaxResults(5).SetProjection(Property.ForName("Id")) 
       .Add(Subqueries.PropertyLt("Time", dcMiddleTime)); 

     crit.AddOrder(Order.Asc("Time")); 
     crit.Add(Restrictions.Eq("Id", id) || Subqueries.PropertyIn("Id", dcAfterTime) || 
       Subqueries.PropertyIn("Id", dcBeforeTime)); 

     return crit.List<Item>(); 

이 NHibernate에 2.0 구문은하지만 같은 당신이 표현을 사용하는 대신 제한의 이전 버전에 대한 진정한 보유하고 있습니다.

내가 테스트 응용 프로그램에서이를 테스트 한 나는이 한 순서는 고유 한 값을 유지하는 열을 그대로 작동합니다 생각

+0

시간이 유일 할 때만 효과가 있지만 PropertyGt/Lt 제한으로 인해 "중간"시간이 여러 행간에 공유되면 실패합니다. 그러나 PropertyGe/Le로 변경하면 작동하지 않습니다. 샘플에서 내 질문의 시간 값을 사용하고 내 뜻을 확인하십시오. Btw, 당신의 코드는 분명히 서브 쿼리에 대한 새로운 것을 가르쳐주었습니다 :-) – HakonB

+0

bleh, 일시적인 실명으로 인해 비 고유 요구 사항을 놓쳤습니다. 데이터 집합에 순차적 순서가 없기 때문에 필요한 답을 제공 할 수있는 방법을 찾을 수 없습니다. – Jaguar

관련 문제