2009-12-07 3 views
1

나는 세트 세트가있는 아티클을 가지고 있습니다. 특정 ID가있는 모든 범주를 포함하는 모든 아티클에 대해 조건 인터페이스를 사용하여 쿼리 할 수 ​​있습니까?NHibernate : 기준에 특정 조건자를 가진 모든 엔티티를 "가진"엔티티를 검색하는 방법

이것은 "in"이 아니며, 나는 모두 필수 카테고리와 그 외의 사람들 만 필요로합니다. 부분 일치가 거기에 있어서는 안됩니다.

현재 내 코드는 다음과 필사적 인 시도와 실패 :

var c = session.CreateCriteria<Article>("a"); 
if (categoryKeys.HasItems()) 
{ 
    c.CreateAlias("a.Categories", "c"); 
    foreach (var key in categoryKeys) 
     c.Add(Restrictions.Eq("c", key)); //bogus, I know! 
} 

답변

1

은 "IN"제한을 사용하지만 범주의 수는 단지 당신이 모든 범주가 일치하는지 확인하기 위해 찾고있는 모든 범주의 수와 동일 일치하지 않도록 보완 부분 집합.

예를 들어, this page, 특히 "Toxi solution"제목 아래의 "Intersection"쿼리를 살펴볼 수 있습니다. '북마크'를 '기사'및 '태그'를 '카테고리'로 바꾸면 특정 문제로 되돌아갑니다. 난 당신이 또한 종류에 그 기사를 가정하고 기준 API

SELECT Article.Id 
FROM Article 
INNER JOIN (
     SELECT ArticleId, count(*) AS MatchingCategories 
     FROM ArticleCategoryMap 
     WHERE CategoryId IN (<list of category ids>) 
     GROUP BY ArticleId 
) subquery ON subquery.ArticleId = EntityTable.Id 
WHERE subquery.MatchingCategories = <number of category ids in list> 
+0

소리가 매우 들리며, nhuser 목록에서 같은 제안을 받았습니다. 나는 이것을 기준에 넣을 수 있는지를 보게됩니다 - 지나치게 복잡하지는 않습니다. – Jan

+0

HQL을 사용하는 쿼리 메소드의 경우 http://stackoverflow.com/questions/948978/nhibernate-query-for-matching-all-tags를 참조하십시오. – iammichael

0

나는 100 % 확실하지 않다,하지만 난 query by example 당신이 원하는 것 같아요.

+0

어쩌면이 방법이 효과가있을 수 있지만 좀 더 명확한 것을 선호합니다. – Jan

0

으로 표현하는 것이 더 쉬울 수 있습니다 하위 쿼리를 사용하여이를 나타낼 수 있다고 생각

SELECT b.* 
FROM tagmap bt, bookmark b, tag t 
WHERE bt.tag_id = t.tag_id 
AND (t.name IN ('bookmark', 'webservice', 'semweb')) 
AND b.id = bt.bookmark_id 
GROUP BY b.id 
HAVING COUNT(b.id)=3 

하나입니다 : 여기에 그들이 거기에 보여 SQL입니다 - 투 - 많은 관계 범주는이 일을 아주 더러운 방법 (I이 정말 자랑 모르지만 작동)

List<long> catkeys = new List<long>() { 4, 5, 6, 7 }; 

if (catkeys.Count == 0) 
    return; 

var cr = Session.CreateCriteria<Article>("article") 
    .CreateCriteria("Categories", "cat0") 
    .Add(Restrictions.Eq("cat0.Id", catkeys[0])); 

if (catkeys.Count > 1) 
{ 
    for (int i = 1; i < catkeys.Count; i++) 
    { 
    cr = cr.CreateCriteria("Article", "a" + i) 
      .CreateCriteria("Categories", "cat" + i) 
      .Add(Restrictions.Eq("cat" + i + ".Id", catkeys[i])); 
    } 
} 

var results = cr.List<Article>(); 

을 여기에 다 대일 재산이라는 기사가 있음을 무엇을 관계를 다시 반복하여 카테고리 ID간에 ​​AND를 보장하는 것입니다. 특히 ID 목록이 커지면 쿼리가 매우 느려야합니다.

나는이 해결책을 권장하지는 않지만 최소한 적절한 것을 찾으면서 뭔가를 할 수 있습니다.

관련 문제