С# + Замок ActiveRecord:HasAndBelongsToMany и коллекции
-
02-07-2019 - |
Вопрос
Допустим, у меня есть связь «многие ко многим» (с использованием атрибута ActiveRecord HasAndBelongsToMany) между сообщениями и тегами (имена объектов домена изменены для защиты невиновных), и мне нужен такой метод, как
FindAllPostByTags(IList<Tag> tags)который возвращает все сообщения, у которых есть все (а не только некоторые) теги в параметре.Как-нибудь я мог бы сделать это с помощью NHibernate Expressions или HQL?Я просмотрел документацию HQL и не смог найти ничего, что соответствовало бы моим потребностям.Надеюсь, я просто упускаю что-то очевидное!
Решение
Вы также можете просто использовать IN
заявление
DetachedCriteria query = DetachedCriteria.For<Post>();
query.CreateCriteria("Post").Add(Expression.In("TagName", string.Join(",",tags.ToArray()) );
Я это не компилировал, поэтому могут быть ошибки
Другие советы
У меня сейчас нет под рукой системы с установленным Castle, поэтому я не тестировал и не компилировал ее, но приведенный ниже код должен делать то, что вы хотите.
Junction c = Expression.Conjunction();
foreach(Tag t in tags)
c = c.Add( Expression.Eq("Tag", t);
return sess.CreateCriteria(typeof(Post)).Add(c).List();
У меня была та же проблема, и я пытался прочитать HQL-документацию, однако некоторые функции, похоже, не реализованы в NHibernate (например, с ключевым словом)
В итоге я пришел к такому решению:
select p FROM Post p JOIN p.Tags tag1 JOIN p.Tags tag2 WHERE tag1.Id = 1 tag2.Id = 2
Это означает, что динамически создайте HQL, используя соединение для каждого тега, а затем сделайте выбор в предложении WHERE.Это сработало для меня.Я попытался сделать то же самое с DetachedCriteria, но столкнулся с проблемой при попытке присоединиться к таблице несколько раз.