2013-04-09 1 views
2

서브 쿼리 "IN"파라미터에 커스텀 SQL을 사용할 수 있습니까? 현재 서브 쿼리 (subQueryEstate)를 성공적으로 구축하고 있지만, 복잡한 데이터 세트를 처리하는 데는 많은 시간이 걸릴 수 있습니다. 다음과 같이 우리의 기존의 서브 쿼리를 사용하여 쿼리를 생성하는 코드는 다음과 같습니다임시 테이블을 사용하는 NHibernate와 커스텀 SQL 서브 쿼리

session.QueryOver(() => cAlias) 
.WithSubquery.WhereProperty(x => x.CPE.ID).In(subQueryEstate) 
.JoinAlias(x => x.Costs,() => aCosts, JoinType.LeftOuterJoin) 
.JoinAlias(x => x.Open,() => aOpen, JoinType.InnerJoin) 
.List(); 

우리가 ID 년대로 채워집니다 임시 테이블 (트랜잭션 수명주기)를 사용하는 아이디어가 실행 속도를 향상시킬 수 있습니다. 아이디어는 임시 테이블에 조인하거나보다 복잡한 원본 대신에 훨씬 간단한 서브 쿼리 (SELECT ID FROM TEMP_TABLE)를 사용하는 것입니다.

NHibernate에서 하위 쿼리로 매핑되지 않은 테이블을 사용할 수 있습니까? 사용자 지정 SQL을 작성하거나 IN 절에 매개 변수로 전달할 분리 기준을 만들 수 있습니까? NHibernate가 나머지 쿼리에 대해 정확한 SQL을 생성하고 있다는 사실을 보존하고 싶습니다.

이상적으로 같은 :

session.QueryOver(() => cAlias) 
.WithSubquery.WhereProperty(x => x.CPE.ID).In("SELECT ID FROM TEMP_TABLE") 
.JoinAlias(x => x.Costs,() => aCosts, JoinType.LeftOuterJoin) 
.JoinAlias(x => x.Open,() => aOpen, JoinType.InnerJoin) 
.List(); 

생각? 아이디어? 우리가 생각하지 못한보다 우아한 해결책이있을 수 있습니다.

+0

내가 여기 최선의 방법이 될 수있는 중 하나 IDS 또는 전체 고장 기록을 반환하는 저장된 프로 시저를 사용하여 생각합니다. – Rippo

답변

1

결국 우리는 임시 테이블을 사용하여 문제를 해결했습니다. 우리의 응용 프로그램은 파이어 버드 데이터베이스를 사용하기 때문에 우리는 "트랜잭션"생명주기를 갖는 4 개의 전역 임시 테이블을 생성했습니다. 즉, 임시 테이블의 데이터는 트랜잭션의 수명 동안 만 유효합니다.

임시 테이블을 만드는 데 사용되는 SQL을 삭제 커밋 행에 전역 임시 테이블 TEMP_TABLE_ID1 (ID BIGINT NOT NULL)을 생성

을 (우리가 사용 사례를 충족하기 위해 네 가지를 만들어 주); CREATE INDEX IDX_TEMP_TABLE_ID1 ON TEMP_TABLE_ID1 (ID);

이제 임시 테이블을 사용하여 마스터 쿼리에서 ID를 체계적으로 채울 수 있습니다. 하위 쿼리를 사용하거나 임시 테이블에 조인하여 후속 쿼리를 필터링하십시오.이 방법은 각 "다운 스트림"쿼리에 대해 큰 하위 쿼리를 사용하는 것보다 훨씬 빠릅니다. 임시 테이블을 사용하여 성능이 크게 향상되고 테이블이 트랜잭션 수명 동안 만 유효하기 때문에 트랜잭션 간 오염 및/또는 데이터 테이블 삭제에 대해 걱정할 필요가 없습니다.

아주 깔끔한 해결책입니다.

글로벌 임시 테이블 (파이어 버드) http://www.firebirdsql.org/refdocs/langrefupd21-ddl-table.html

+1

나는 여전히 임시 테이블을 매핑하기 위해 NHibernate를 얻었는지 궁금하다. "커밋 삭제 행"을 사용하기 때문에 동일한 트랜잭션에서 해당 행을 사용한다고 가정합니다. 그래서 당신은 NHibernate에서 동시에 매핑을 수행합니까? – Joppe

+0

@paligap 당신은 이것을 nhibernate에 어떻게 연결 시켰는 지 설명 할 수 있습니까? 나도 같은 문제가 있니? – Rafi

관련 문제