2011-09-19 2 views
1

NH 3.1을 사용하는 프로젝트가 있고 여기까지 모든 것에 대해 QueryOver 구문을 사용하고 있습니다.NHibernate QueryOver 값 컬렉션

이 프로젝트의 한 측면은 읽기 전용 액세스 권한이 있고 완전히 다른 DBMS (Oracle VS MSSQL)를 사용하는 조직 전체 데이터베이스에 존재합니다. 그래서 대신 Iset<Bar>을 필요없이 해당 개체 (바) 다 대다 표준을 사용하여 테이블

FooBars 
FooID int not null PK 
BarID int not null PK 

그리고 내 도메인 객체에 내 개체 (FOOS)에서 참조를 저장하는 대신 수동으로 매핑하는 ISet<int> BarIDs있다 테이블에 FooBars. 이것은 NH가 불가능한 일을 시도하지 못하도록하고 Bars 테이블까지 모든 단계에 참여합니다 (BarRepository.Get()을 사용하여 나중에 막대의 세부 정보를 검색 할 수 있습니다. 필요하다면이 경우 I wouldn 왜냐하면 반환 된 객체의 목록을 필터링하기 위해 ID가 필요하기 때문입니다.)

주어진 어떻게 BarIDs에있는 요소가 포함되어 있습니다 SelectedBars?

...FROM foos INNER JOIN foobars on foo.fooID = foobars.fooID WHERE barID IN (...) 

답변

0

3 년 후, 나는 이것을 어떻게 풀 었는지보고하기 위해 돌아 왔습니다.

public class Foo :Entity { 
    public virtual ISet<FooBar> BarIDs { get; protected internal set; } 
} ... 

public class FooBar :Entity { 
    protected internal FooBar() { } 
    protected internal FooBar(Foo f, int BarID) { ... } 
    public virtual Foo Foo { get; protected internal set; } 
    public virtual int BarID { get; protected internal set; } 
} 

이것은 기본적으로 스테판이 제안한 것이며 관련 게시물에서 암시 된 내용입니다. 여분의 엔티티를 작성하고이를 참조하는 오버 헤드를 먹기 만하면됩니다. 나는 두 개의 데이터베이스 사이의 경계를 다루기 때문에 전체 Bar 객체 대신 BarID를 저장한다는 것을 기억하십시오 : 막대는 Foos와는 다른 플랫폼의 완전히 다른 데이터베이스에 저장됩니다. 그렇지 않으면 당연히 Foo에게 ISet<Bar>이 있음을 알리는 것이 훨씬 낫습니다.

session.QueryOver<Foo>().JoinQueryOver<FooBar>(f => f.BarIDs). 
    WhereRestrictionOn(b => b.BarID).IsIn(...)... 

그것은이 같은 데이터베이스 경계를 ​​넘어 작업, 흥미로운 문제입니다 : SelectedBarIDs에 의해

찾기, FOOS는 Thilak 제안 훨씬처럼, 다음 쉽다. 나는 그것을해야하는 것을 좋아하지 않는다고 말할 수는 없지만, 누군가가 바의 목록을 유지하고 그것을 사용할 수있게 할 시간이 있다면, 나는 똑같은 일을하는 데 거대한 자원 낭비가 될 것이다. . 래퍼 클래스를 사용하는 것이 비효율적이지 않기 때문에 합리적인 비용이 들게됩니다.

1

시도 같은

SQL 뭔가 :

session.QueryOver<Foo>() 
     .JoinQueryOver(x => x.FooBars) 
     .WhereRestrictionOn(x => x.BarId).IsIn(...) 
2

이 QueryOver 불가능합니다. 2 년 전 나는 similar question about filtering value collections을 가졌습니다. (참고 : QueryOver는 Criteria API를 기반으로합니다.)

저는 100 % 확실하지는 않지만 HQL에서 작동 할 것입니다. 그것은 훨씬 더 강력합니다.

QueryOver 조건에 SQL 문을 포함 할 수 있습니다.

왜 엔티티 목록으로 매핑하지 않는지 저는 이해가 가지 않습니다. 불필요한로드를 피하기 위해 지연로드가 있습니다. 가끔은 약간의 트레이드 오프가 있습니다. 데이터베이스에 접근하지 않고 NH 프록시의 ID에 액세스 할 수 있습니다. 매핑 ID는 일반적으로 삶을 훨씬 어렵게 만듭니다.

+0

그래, 나는 2 년 후에 무언가가 바뀌었을 것이라는 헛된 희망을 가지고 있었다.게으른 로딩은주의를 기울이지 않으면 데이터베이스를 공격하려고 시도하고 MSSQL 데이터베이스의 테이블을 Oracle 데이터베이스에 조인하려고 시도하기 때문에 작동하지 않습니다. 하지만 난 유일한 속성으로 단지 ID와 래퍼 클래스 'DummyBar'쓸 수 있습니다 ... 그냥 automapper 그것을 무시하도록해야합니다. –

+0

이 두 달 후로 돌아와 ... 나는 BarProxy 클래스를 작성하려고했지만 그 다음에 "이 술집과 관계가있는 정보를 찾는다"라는 쿼리가 나오자 SQL이 BarProxy 테이블에 조인하려고했습니다 a) 존재하지 않았고 b) 그것이 존재했다하더라도 비어있을 수 있습니다 (실제 데이터는 외부 데이터베이스에 있음). 그래서 우리는 지금 HQL이나 원시 SQL을 시도 할 것입니다. –

관련 문제