Как перевести «где не в» в запрос NHibernate, где таблица подзапроса не является сущностью? - PullRequest
1 голос
/ 06 марта 2012

У меня есть две сущности: User и Notice, они связаны между собой через таблицу DismissedNoticeToUser (UserId и NoticeId - соответствующие столбцы).

Вот мое отображение FluentNHibernate для класса User:

mapping.HasManyToMany<Notice>(u => u.DismissedNotices)
    .Table("DismissedNoticeToUser")
    .ParentKeyColumn("UserId")
    .ChildKeyColumn("NoticeId")
    .Inverse();

Каждый раз, когда пользователь «отклоняет» уведомление, в класс DismissedNoticeToUser добавляется пара User.Id и Notice.Id. Это легко в коде:

var notice = this.session.Load<Notice>(noticeId);
var user = this.session.Load<User>(this.userSession.Id);
user.DismissedNotices.Add(notice);

Если я хочу перечислить все уведомления , а не , отклоненные пользователем, я пишу что-то вроде этого в сыром SQL:

select * from [Notice]
    where Id not in 
    (select NoticeId from [DismissedNoticeToUser] where UserId=@userId)

Однако я не совсем уверен, как сделать то же самое с помощью NHibernate. Я пробовал следующее, но он выполняет левое соединение в уведомлениях пользователя как отдельный запрос.

this.session.Query<Notice>().Where(n => !user.DismissedNotices.Contains(n));

Я мог бы остановиться и использовать NHibernate для написания необработанного SQL, но я чувствую, что, возможно, что-то упустил. Мне все равно, какой API запросов NHibernate я использую.

Ответы [ 3 ]

1 голос
/ 07 марта 2012

Если вы не можете сопоставить пользователей с Notice, попробуйте также кодировать Query против Query. Я не пробовал устанавливать партнерские отношения с Load to Query, поскольку использование Load to Query может привести к тому, что NH сгенерирует отдельные запросы.

Попробуйте это:

this.session.Query<Notice>().Where( n => 
    this.session.Query<User>().Any(u => u.UserId == "007"
            && !u.DismissedNotices.Contains(n) );
1 голос
/ 07 марта 2012

Я думаю, что следующий пост описывает, как вы можете запросить эти многие ко многим отношениям:

Запрос FluentNHibernate для объектов отношения «многие ко многим»

Вероятно, существует множество других похожих сообщений на этот счет.

Редактировать

Вот пример ближе к тому, что вы просите:

var subquery = QueryOver.Of<Notice>()
                .JoinQueryOver<User>(x => x.DismissedNotices)
                .Where(x => x.Id == userId)
                .Select(x => x.Id);

IList<Notice> groupsFound =
         session.QueryOver<Notice>()
                .WithSubquery.WhereProperty(x => x.Id).NotIn(subquery)
                .List<Notice>();

Если вы хотите сгенерировать запрос точно так же, как у вас выше, я не уверен, что вы сможете сделать это, если вы не отобразите таблицу DismissedNoticeToUser как сущность. Если бы вы сделали это, вы могли бы сделать что-то вроде этого:

var subquery = QueryOver.Of<DismissedNoticeToUser>()
                        .Where(x => x.UserId == userId)
                        .Select(x => x.NoticeId);

IList<Notice> noticesFound = session.QueryOver<Notice>()
                               .WithSubquery.WhereProperty(x => x.Id).NotIn(subquery)
                               .List<Notice>();
0 голосов
/ 07 марта 2012

Ты почти там, изменение Содержит в Любой:

string userId = "007";

this.session.Query<Notice>().Where( n => 
    !n.Users.Any(x => x.UserId == userId) );
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...