Фильтрация и проектирование ассоциации с использованием NHibernate QueryOver - PullRequest
3 голосов
/ 01 сентября 2011

Предположим, у вас есть объект, похожий на этот:

public class Mailinglist
{
    public virtual Guid Id { get; set; }
    public virtual ICollection<Subscriber> Subscribers { get; set; }
}

Отображение NHibernate для объекта соответствует ожидаемому: Id - это идентификатор, а Subscribers - с помощью <set> и<many-to-many> со ссылкой на Subscriber сущность.

Теперь я нахожусь в ситуации, когда у меня есть экземпляр Mailinglist, и мне нужно получить список первых 100 подписчиков, соответствующих какому-либо фильтру на Subscriberсвойства.Из-за ограничений производительности и количества данных в базе данных myMailinglist.Subscribers.Where().Take() не вариант.Поэтому я пытаюсь собрать запрос для NHibernate, который будет извлекать только 100 Subscriber экземпляров из базы данных.

Моя первоначальная попытка (без какой-либо фильтрации) выглядит следующим образом:

var subscribers = session
    .QueryOver<Mailinglist>()
    .Where(m => m.Id == myMailinglistId)
    .JoinQueryOver(m => m.Subscribers)
    .Take(100)
    .List();

Это, очевидно, неправильно, так как список, который я получаю, содержит 100 ссылок на Mailinglist, о котором я уже знаю.Однако сгенерированный SQL выглядит довольно хорошо, поэтому я думаю, что мне просто нужно явно добавить проекцию / преобразование.

Я пытался найти какую-то соответствующую документацию, чтобы помочь мне в этом, но, похоже, не могу найтивсе, что касается такого рода запросов.Может кто-нибудь намекнуть мне?

Ответы [ 2 ]

2 голосов
/ 02 сентября 2011
var subquery = QueryOver.Of<Mailinglist>()
    .Where(m => m.Id == myMailinglistId)
    .JoinQueryOver(m => m.Subscribers, () => subscriber)
    .Select(m => subscriber.Id);

var subscribers = session.QueryOver<Subscriber>()
    .WithSubquery.WhereProperty(s => s.Id).In(subquery)
    .Take(100)
    .List();
0 голосов
/ 05 сентября 2011

Не проще ли прочитать HQL?

Не тестировал, но что-то в строках:

Query query = 
 session.createQuery("from Mailinglist m where m.subscriber = :code ")
.SetMaxResults(100)
.setParameter("code", "%john%");
List list = query.list();

setMaxResults должно переводиться в T-SQL "выберите top 100 ... "

...