这是我的域:
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; }
}
我想要得到的是:
论坛主题列表以及每个论坛主题的最新论坛消息中的前 5 个
可以在 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; }
}
所以一个频道有很多类别,一个类别有很多文章。
我在这里要做的是为每个频道抓取 TOP N 文章(忽略它们来自不同类别的事实)。这些文章将显示在我的门户网站的登录页面上。
在应用程序中,我使用仅包含实际数据库数据子集的 ViewModel。这是我的复合 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还不是很熟悉。是否有可能通过一次往返和水合 DTO 获得所有东西?在 QueryOver 中使用类似 ROW_NUMBER() OVER (PARTITION BY....) 的东西?我不想使用 HQL 或原始 SQL。