NHibernate - это объект / реляционный картограф, поэтому, чтобы правильно задать вопрос «как мне написать этот запрос», вам нужно предоставить достаточно информации, чтобы потенциальные ответчики могли понять, как выглядят эти три вещи:
- Классы сущностей NHibernate (это часть Object )
- Таблицы базы данных (это реляционная часть)
- Отображения , будь то HBM.XML, FluentNH и т. Д.
Давайте предположим, что ваши сущности выглядят примерно так:
public class AccountProfile
{
public virtual int Id { get; set; }
public virtual string Name { get; set; }
public virtual IList<NewsFeed> NewsFeeds { get; set; }
/// <summary>
/// People following me.
/// </summary>
public virtual IList<AccountProfile> Followers { get; set; }
/// <summary>
/// People I am following.
/// </summary>
public virtual IList<AccountProfile> Following { get; set; }
}
public class NewsFeed
{
public virtual int Id { get; set; }
public virtual AccountProfile AccountProfile { get; set; }
public virtual string Name { get; set; }
}
... где Последователи и Последующие являются противоположными сторонами отношений «многие ко многим». Этого должно быть достаточно, чтобы большинство людей смогли заполнить пробелы и интуитивно понять, как выглядят таблицы и сопоставления.
Теперь, когда у нас есть это основание, давайте работать над запросом. Ваш запрос будет немного легче обработать, если мы переписаем его, чтобы использовать соединение вместо подзапроса:
select newsfeed.*
from
newsfeed
inner join follow
on newsfeed.AccountProfileID = follow.FollowerID
where follow.AccountProfileID='1'
Этот запрос должен в точности соответствовать поведению исходного запроса, быть более совместимым с мышлением реляционной базы данных и, возможно, немного более эффективным.
Эквивалентный запрос NHibernate QueryOver (мой предпочтительный API запросов) будет выглядеть так:
AccountProfile accountProfileAlias = null;
AccountProfile followingAlias = null;
var feeds = session.QueryOver<NewsFeed>()
.JoinAlias(x => x.AccountProfile, () => accountProfileAlias)
.JoinAlias(() => accountProfileAlias.Following, () => followingAlias)
.Where(() => followingAlias.Id == 1)
.List();
Давайте переведем этот запрос на английский: "Выберите список новостных лент, принадлежащих всем людям, которые подписаны на учетную запись № 1." Однако у меня есть ощущение, что вы имели в виду "Выберите список из новостных лент, принадлежащих всем учетным записям, за которыми следует учетная запись # 1 ", что мне кажется немного более полезным. В QueryOver это выглядит следующим образом (замените Following на Followers).
AccountProfile accountProfileAlias = null;
AccountProfile followerAlias = null;
var feeds = session.QueryOver<NewsFeed>()
.JoinAlias(x => x.AccountProfile, () => accountProfileAlias)
.JoinAlias(() => accountProfileAlias.Followers, () => followerAlias)
.Where(() => followerAlias.Id == 1)
.List();
Если кто-то еще хочет попробовать это с помощью LINQ-провайдера NHibernate, a.k.a. session.Query
, не стесняйтесь, но лично у меня не так много опыта работы с этим API.