これが私のドメインです:
public class ForumTheme
{
public virtual String Name { get;set; }
}
public class ForumTopic
{
public virtual IList<ForumTheme> Themes { get;set; }
}
public class ForumMessage
{
public virtual IList<ForumTopic> Topics { get;set; }
public virtual DateTime DatePosted { get; set; }
}
私が取得したいものは次のとおりです。
各ForumThemeの最新のForumMessageのトップ5を含むForumThemesのリスト
NHibernateでそれを行うことは可能ですか?
アップデート
別の可能なシナリオがあります。
ドメイン
ドメインは、典型的な階層的なブログ/ニュースサイトを記述します。
public class Channel
{
public virtual Int32 Id { get; set; }
public virtual String Name { get; set; }
public virtual IList<Category> Categories { get; set; }
}
public class Category
{
public virtual IList<Article> Articles { get; set; }
}
public class Article
{
public virtual String Name { get; set; }
public virtual DateTime PublishDate { get; set; }
public virtual Boolean IsActive { get; set; }
}
したがって、1つのチャネルには多くのカテゴリがあり、1つのカテゴリには多くの記事があります。
私がここでやりたいのは、各チャンネルのトップNの記事を取得することです(それらが異なるカテゴリーから来ているという事実を無視します)。記事は私のポータルのランディングページに表示されます。
アプリケーションでは、実際のデータベースデータのサブセットのみを保持するViewModelsを使用します。これが私の複合ViewModelです
DTO
public class ChannelDto
{
public Int32 Id { get; set; }
public String Name { get; set; }
public List<ArticleDto> Articles { get; set; }
public class ArticleDto
{
public String Name { get; set; }
}
}
チャネルを取得するためのクエリは非常に簡単です(アクティブな記事が含まれているチャネルのみを表示します)。
Category categoryAlias = null;
Article articleAlias = null;
ChannelDto.ArticleDto articleDtoAlias = null;
List<ChannelDto> channels = _session.QueryOver<Channel>()
.Inner.JoinAlias(x => x.Categories, () => categoryAlias)
.Inner.JoinAlias(x => categoryAlias.Articles, () => articleAlias)
.Where(x => articleAlias.IsActive)
.SelectList(list => list
.Select(x => x.Id)
.Select(x => x.Name)
)
.List<Object[]>
.Select(x => new ChannelDto
{
Id = (Int32) x[0],
Name = (String) x[1]
})
.ToList();
上記のクエリは、アクティブな記事があるチャンネルのリストを表示します。今、私は記事自体を取得します:
foreach(var channel in channels)
{
channel.Articles = _session.QueryOver<Channel>()
.Inner.JoinAlias(x => x.Categories, () => categoryAlias)
.Inner.JoinAlias(x => categoryAlias.Articles, () => articleAlias)
.Where(x => x.Id == channel.Id)
.OrderBy(x => articleAlias.PublishDate).Desc
.SelectList(list => list
.Select(x => articleAlias.Name).WithAlias(() => articleDtoAlias.Name)
)
.Take(5)
.List<Object[]>
.Select(x => new ChannelDto.ArticleDto
{
Name = (String) x[0]
})
.ToList();
}
ただし、上記の2つのクエリには、SELECT+1の問題が発生します。先物を使うと、より少ない往復でそれができると思います。私はまだNHibernateにあまり詳しくありません。1回のラウンドトリップですべてを取得してDTOをハイドレイトすることは可能ですか?QueryOverでROW_NUMBER()OVER(PARTITION BY ....)のようなものを使用しますか?HQLや生のSQLは使いたくありません。