Как писать подзапросы как псевдонимы, используя Criteria Api с NHibernate

Привет, ребята, скажите, у меня есть такие сущности и сопоставления:

public class Episode
{
    Guid Id {get;set;}
    String Title {get;set;}
    List<Group> Groups {get;set;}
}

public class Group
{
    Guid Id {get;set;}
    DateTime PubDate {get;set;}
}

public class EpisodeMap : ClassMap<Episode>
{
    public EpisodeMap()
    {
        //other mappings..
        Map.HasMany(ep => ep.Groups);
    }
}

Итак, в основном в эпизоде ​​много групп. Каждая группа имеет PubDate, поэтому у эпизода много PubDate.

Я пытаюсь написать запрос с помощью API критериев NHibernate, который позволяет мне запрашивать эпизоды и упорядочивать их по PubDate, учитывая, что у меня есть идентификатор группы.

По сути, как мне написать эквивалентный запрос Criteria API для этого SQL-запроса:

Select 
    e.*, 
    (Select top 1 ReleaseDate From EpisodeGroups where EpisodeFk = e.Id and GroupFk = @GroupId) as myPubDate 
From Episodes e 
Order By myPubDate

Пожалуйста помоги! ура, ребята


person andy    schedule 07.01.2011    source источник


Ответы (1)


public DetachedCriteria BuildCriteria(int episodeId, int groupId)
{

    var groupCriteria = DetachedCriteria.For<Groups>()
        .Add(Restrictions.Eq("this.Id", groupId))
        .Add(Restrictions.Eq("Group.Id", groupId)) 
        .AddOrder(Order.Asc("Group.PubDate"));

    return DetachedCriteria.For<EpisodeGroups>()
               .Add(Restrictions.Eq("this.Id", episodeId))
               .Add(Subqueries.PropertyIn("this.Groups", groupCriteria)
               .SetMaxResult(1);
}

Тогда вы можете сделать что-то вроде этого ...

var episodes = _repository.ExectueCriteria<EpisodeGroups>(BuildCriteria(episodeId, groupId))

В качестве особого соображения причина, по которой вы хотели бы с нетерпением загрузить объект Group, заключается в том, что вы хотите использовать LINQ для сравнения PUBDATE позже в своей бизнес-логике, а не использовать строгие отдельные критерии.

Мы обнаружили, что активная загрузка атрибутов сущности снижает общее количество обращений к нашей базе данных.

Нет гарантий, что этот код работает ... но он должен, по крайней мере, помочь вам начать, удачи :)

person Timbob    schedule 11.01.2011
comment
+1 эй тимбоб, большое спасибо. Я действительно боролся с API критериев, я считаю его очень не интуитивным! Я попробую и расскажу, как у меня дела, спасибо за отличное объяснение - person andy; 11.01.2011
comment
Привет, Тимбоб, хорошо, только что взглянул. он почти готов, но в моем примере sql вы заметите, что только GroupId является переменной. EpisodeId является частью запроса ...? - person andy; 11.01.2011
comment
Если я понимаю, что вы пытаетесь сделать и как отображаются остальные ваши объекты, ограничения, т.е. (Restrictions.Eq (this.Id, episodeId)) должен учитывать это. Я не могу вспомнить навскидку, нужно ли добавлять псевдонимы к группам и группам эпизодов, чтобы ссылаться на их идентификаторы. Другими словами, вы не сможете использовать this.Id, но вам придется использовать Group.Id и Episode.Id соответственно. Я надеюсь, что в этом есть смысл. - person Timbob; 11.01.2011
comment
@andy, обратите внимание, что награда НЕ будет присуждаться автоматически. Вы должны сделать это до истечения срока его действия! - person Arjan; 16.01.2011
comment
@andy, слишком плохо, слишком поздно. Поскольку вы сами не назначали награду, теперь система присудила половину ее стоимости в соответствии с некоторым правилам. В следующий раз не забудьте наградить его самостоятельно! - person Arjan; 17.01.2011