Запрос NHibernate на совпадение всех тегов - PullRequest
1 голос
/ 04 июня 2009

Вот мои соответствующие классы:

public class Item {
    public virtual int Id { get; protected set; }
    public virtual IList<Tag> Tags { get; set; }
}

public class Tags {
    public virtual int Id { get; protected set; }
    public virtual string Name { get; set; }
    public virtual IList<Item> Items { get; set; }
}

Они сопоставлены со многими ко многим. Промежуточная таблица называется ItemsToTags.

Вот вопрос:

Учитывая список строк, как мне создать запрос NHibernate, который возвращает все Item с всеми Tag с Name с соответствующими строками в данном списке?

Это сигнатура функции:

IList<Item> GetItemsWithTags(IList<string> tagNames);

Мне нужно что-то вроде:

from Item item
where !tagsNames.Except(
    from item.Tags select item.Tags.Name
).Any()
select item

Заранее спасибо за любую помощь.

1 Ответ

2 голосов
/ 05 июня 2009

Вы определенно можете сделать это с HQL; Я успешно проверил это.

var items = session.CreateQuery("SELECT i.Id FROM Item i JOIN i.Tags tags WHERE tags.Name IN(:tags) GROUP BY i HAVING COUNT(DISTINCT tags) = :tagCount")
        .SetParameterList("tags", tagNames)
        .SetInt32("tagCount", tagNames.Count)
        .List();

Это даст вам список Item идентификаторов, которые вы можете использовать для получения Item s. Комбинация GROUP BY и HAVING может быть неэффективной на некоторых СУБД. Есть другой метод запроса, использующий итеративные объединения, которые могут быть более эффективными в определенных СУБД, но я не могу заставить его работать (возможно, вообще невозможно с Criteria). Если я когда-нибудь это сделаю, я обновлю свой ответ.

...