2012-12-07 3 views
0

맵핑 된 콜렉션의 결과 세트를 제한하려고합니다.상위 엔티티를 제한하지 않고 하위 엔티티를 제한하십시오 - NHibernate

public class Table1 { 
    public virtual long Id { get; set; } 
    public virtual IList<Table2> Table2s { get; set; } 
} 


public class Table2 { 
    public virtual long Id { get; set; } 
    public virtual long Table1Id { get; set; } 
    public virtual Table1 Table1 { get; set; } 
    public virtual string Field { get; set; } 
} 

public class Table1Map : ClassMap<Table1> { 
    public Table1Map() { 
     Table("Table1"); 
     Id(x => x.Id).Column("Id").Not.Nullable().CustomType("Int64").GeneratedBy.Native(); 
     HasMany<Table2>(x => x.Table2s).Inverse().Not.LazyLoad().KeyColumns.Add("Table1Id").Fetch.Join(); 
    } 
} 

public class Table2Map : ClassMap<Table2> { 
    public Table2Map() { 
     Table("Table2"); 
     Id(x => x.Id).Column("Id").Not.Nullable().CustomType("Int64").GeneratedBy.Native(); 
     Map(x => x.Table1Id).Column("Table1Id").Not.Nullable().CustomType("Int64"); 
     Map(x => x.Field).Column("Field").Not.Nullable().CustomType("AnsiString").Length(25); 
     References<Table1>(x => x.Table1, "Table1Id").Cascade.None(); 
    } 
} 

나는 모든 Table1의를 선택합니다 : 여기

간단한 모델이다. 또한 특정 기준 ( Table2.Field = 'value')을 충족하는 모든 Table2을 선택하려고하지만, Table1을 제한하고 싶지 않으므로 기준을 충족시키지 않으면 null Table2을 선택하십시오. 내가 SQL에서이 작업을 수행하려면 내가 할 거라고 다음

SELECT * 
FROM 
Table1 
LEFT OUTER JOIN Table2 ON Table1.Id = Table2.Table1Id 
WHERE 
Table2.Field = 'value' or Table2.Field IS NULL 

어떻게 원하는 결과를 달성하기 위해 내 NHibernate에 쿼리를 구성해야합니까? Table1 s의 목록을 원하고 각각 Table1 (Table2이 기준을 충족시키지 않았기 때문에) Table2의 빈 목록 또는 creteria와 만나는 Table2의 목록을 원합니다.

나는 다음과 같은 일을 시도하고있다, 그러나 이것은 분명히 작동하지 않습니다

List<Table1> result = new List<Table1>(); 
IQueryable<Table1> query = session.Query<Table1>(); 
if (value != null) { 
    query = query.Where(x => x.Table2s.Field == value); 
} 
query = query.OrderBy(x => x.Id); 
result = query.ToList(); 

답변

0

나는이 이렇게 길 수 없습니다 생각합니다. Hibernate는 lazyloading이 활성화되어 있지 않으면 모든 속성을 가진 완전한 엔티티를로드한다. 모든 table2가없는 상태에서 table1 유형의로드 된 엔터티를 저장하면 최대 절전 모드를 수행해야하는 이유는 무엇입니까?

table1의 관련 부분과 기준에 맞는 table2 하위 목록이 포함 된 일종의 viewobject (dvo)를 만들어야합니다. 선택은 projection으로 수행 할 수 있습니다.

0

꽤 좋은 설명서가 있습니다 - 16.4. 협회

http://nhibernate.info/doc/nh/en/index.html#queryqueryover-associations

QueryOver 구문이

IQueryOver<Table1, Table2> myQuery = 
    session.QueryOver<Table1>() 
    .Left.JoinQueryOver<Table2>(t => t.Table2s) 
    .Where(
     Restrictions.Or(
     Restrictions.On<Table2>((t2) => t2.ID).IsNull, 
     Restrictions.On<Table2>((t2) => t2.Field).IsLike("value") 
     ) 
     ); 
var list = myQuery.List<Table1>(); 

과 같을 것이다 다음 list는 기준을 충족 모든 조합의 컬렉션을 반환합니다. (나중에 또는 별개의 다른 주사위를 추가 할 수 있습니다 ...)

+0

이것은 꽤 좋은 대답이지만 다소 제한적입니다. 'Table1'이'Table2' 컬렉션을 가지고있을뿐만 아니라 당신이 또한 필터링하고 싶은'Table3' 컬렉션이 있다면? 제공된 메소드는 두 개의 엔티티 만 수용합니다. 보다 일반적인 방법이 있습니까? 거기에 또 다른 접근 방식이 있습니까? 감사! – Michael

+0

예! ;) NHibernate Criteria API는 매우 강력하다. 당신은 투영을 사용할 수 있습니다 (일부 속성을 선택하고 distinct ... sum, avg를 선택하십시오) 당신은 어떻게 든 참여할 수 있습니다 ... WHERE 절에서 필터링 할 수 있습니다. 제발,보세요 문서 (http://nhforge.org/doc/nh/en/index.html#querycriteria) 또는 Ayende의 블로그 –

+0

실례가 있습니까? 나는 나의 예를 들어 특히 도움이되는 문서를 찾지 못한다. 위의 제안을 구현하려했으나 지금은 "Table3"을 무시하고 결과를 얻지 못했습니다. 여러 개의 매핑 된 컬렉션이있는 강력한 Criteria API를 사용하는 작업 예제가 있다면 큰 도움이됩니다! – Michael

관련 문제