Queryover, где id отсутствует в списке
Я боролся с этим некоторое время, поэтому я надеюсь, что некоторые из вас могут помочь специалистам QueryOver.
У меня есть список сообщений в блогах. Вы можете проголосовать за каждое сообщение в блоге, и я хотел бы (среди прочего) получить список сообщений, в которых пользователь не голосовал.
Сначала я думал о том, чтобы сделать что-то вроде:
Session.QueryOver<BlogPost>()
.WhereRestrictionOn(bp => bp.Id)
.NotIn(existingBlogPostVotes);
(existingBlogPostVoteIds - это идентификаторы проголосовавших блогов)
Но это не существует в структуре QueryOver.
Я узнал, что могу сделать это в следующих критериях:
var crit =
Session.CreateCriteria<BlogPost>()
.Add(Restrictions.Not(Restrictions.In("Id",existingBlogPostVotes)));
Но я бы сделал это в QueryOver, а не в критериях.
Как это сделать в QueryOver?
Ответы
Ответ 1
Как насчет Not.IsIn()
:
Session.QueryOver<BlogPost>()
.WhereRestrictionOn(bp => bp.Id)
.Not.IsIn(existingBlogPostVotes);
Опционально это может быть сделано и в поставщике Linq:
Session.Query<BlogPost>()
.Where(bp => !existingBlogPostVotes.Contains(bp.Id));
Ответ 2
Как насчет стандартного запроса, в котором вы используете вспомогательный запрос в предложении where. У меня нет визуальной студии для меня, чтобы проверить синтаксис, но по существу это вызывает все записи в блоге, где не существует записи blogPostVote для текущего пользователя.
Session.QueryOver<BlogPost>()
.Where(bp => bp.Id)
.Where(
!Session.QueryOver<BlogPostVotes>()
.Where(blogPostVotes => blogPostVotes.BlogPostId == bp.Id)
.Where(blogPostVotes => blogPostVotes.UserId == currentUserId)
.Any());
Это должно дать вам результат, который вы ищете. Я знаю, что мой синтаксис будет работать в Linq To Sql, если он не работает для NHibernate, посмотрите здесь этот ответ (Подзапросы с QueryOver)