Как использовать Contains () в сценарии «многие ко многим»? - PullRequest
2 голосов
/ 04 августа 2011

Nhibernate 3.0

Привет

Классический сценарий блога:

  • Блог
    • Метки
  • Сообщения
    • Теги (многие ко многим)

Когда я хочу показать только сообщения, содержащие определенный тег, я использую функцию Contains(), например:

var tag = session.Query<Tag>().Single(x => x.Name == "C#");
var postsByTag = session.Query<Post>().Where(x => x.Tags.Contains(tag));

Это работает как шарм, а NHibernate генерирует правильный SQL.

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

var tags = session.Query<Tag>().Where(x => x.Name.StartsWith("Nhibernate"));
var postsByTag = session.Query<Post>().Where(x => x.Tags.Any(t => tags.Contains(t)));

Работает как положено, postsByTag содержит только сообщения, содержащие один из выбранных тегов. Моя проблема в этом заключается в том, что NHibernate, к сожалению, не знает, как перевести это на SQL, поэтому вместо использования WHERE IN он просто получает все сообщения из базы данных и затем выполняет фильтрацию. Это огромная проблема для меня, потому что блог может содержать миллионы сообщений.

У кого-нибудь есть решение этой проблемы?

Заранее спасибо!

Ответы [ 2 ]

2 голосов
/ 04 августа 2011

После работы с поставщиками LINQ я могу понять его проблемы. К счастью, есть лучший способ, чем содержит и любой.

from post in session.Query<Post>
from tag in post.Tags 
where tag.Name.StartsWith("blah")
select post
0 голосов
/ 04 августа 2011

HQL

Вам следует взглянуть на язык запросов Hibernate, на самом деле есть несколько способов сделать это с помощью HQL или даже с использованием псевдонимов и ICriterion.

Hhibernate HQL, где IN запрос http://ayende.com/blog/4023/nhibernate-queries-examples
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...