Я безуспешно пытался отфильтровать коллекцию дочерних объектов в течение нескольких часов, как и, наконец, поднял руки!Я новичок в NHibernate и надеялся на пару указателей на это.Я пробовал различные ICriteria и т. Д. Без удачи.Я просто не понимаю.
У меня есть родительский объект 'Post' с коллекцией дочерних объектов 'Comment'.Коллекция отображается в виде набора с инверсией на стороне комментария.
Я пытаюсь вернуть только комментарии со значением перечисления статуса 'Comment.Approved'
части классов сущностей выглядят следующим образом:
public class Post
{
public virtual Guid Id { get; protected set; }
private ICollection<Comment> _comments;
public virtual ICollection<Comment> Comments
{
get { return _comments; }
protected set { _comments = value; }
}
}
public class Comment
{
public virtual Guid Id { get; protected set; }
public virtual Post Post { get; set; }
public virtual CommentStatus Status { get; set; }
}
Мой поисковый код выглядит сейчас так:
var Id = __SomeGuidHere__;
var post = _session
.CreateCriteria<Post>()
.Add(Restrictions.Eq("Id", Id))
.UniqueResult<Post>();
var comments = _session.CreateFilter(post.Comments, "where Status = :status").SetParameter("status", CommentStatus.Approved).List<Comment>();
Хотя это работает, SQL не кажется очень эффективнымЯ ожидал, что смогу перевести следующий SQL-код во что-то похожее в HQL или в ICriteria некоторого вида:
SELECT * FROM posts p LEFT JOIN comments c ON p.PostId = c.PostId AND c.Status = 0 WHERE p.PostId = '66a2bf13-1330-4414-ac8a-9d9b00ea0705';
Здесь я рассмотрел различные ответы, относящиеся к этому типу запроса, ипохоже, что ни один из них не рассматривает этот конкретный сценарий.
Возможно, здесь что-то очень простое, что я упускаю, но сейчас я слишком устал, чтобы это увидеть.Мы надеемся, что кто-то лучше с NHibernate может указать мне правильное направление.
Спасибо за ваше время.
Редактировать: Все еще борются с этим, некоторые из ответов здесьхорошо, что я начинаю думать, что моя сущность поста должна быть переосмыслена для выполнения самой фильтрации, или что мне следует реализовать ViewModel для фильтрации комментариев, которые я хочу.Однако этот вопрос все еще остается, даже если только с академической точки зрения.
Я обновил выбор до HQL и попробовал:
var post = _session
.CreateQuery("select p from Post as p left join fetch p.Comments as c where p.Id = :id and c.Id in (select ac from p.Comments ac where ac.Status = :status)")
.SetParameter("id", Id)
.SetParameter("status", CommentStatus.Approved)
.UniqueResult<Post>();
Это работает, пока сообщение имеет утвержденныйкомментарий, в противном случае я не получаю сообщения из-за SQL, сгенерированного с использованием AND в предложении where.
Кто-нибудь?Я в тупике!
Обновление: Спасибо всем, кто ответил, это было полезно и заставило меня пересмотреть части моей модели.Поскольку наиболее часто используемые комментарии в качестве дочерних элементов сообщения используются при просмотре сообщения, в этом сценарии должны просматриваться только утвержденные комментарии.В большинстве других сценариев, которые я могу себе представить, комментарии будут доступны напрямую и будут отфильтрованы по статусу, что, конечно, прямо вперед.
Я обновил свои отображения, чтобы отфильтровать все сообщения> загрузка комментариев, чтобы загружать только утвержденные сообщения, как показано(в FluentNHibernate):
HasMany(x => x.Comments).Where(x => x.Status == CommentStatus.Approved)
.AsSet()
.Inverse()
.KeyColumn("PostId")
.ForeignKeyConstraintName("PostComments")
.OrderBy("CreatedOn")
.Cascade.AllDeleteOrphan();
Хотелось бы пометить все как ответ, так как все помогло мне решить эту проблему, но Питер первым указал, что я могу думать о модели неправильно.
Спасибо всем.