gpt4 book ai didi

c# - NHibernate 每组前 N 行

转载 作者:行者123 更新时间:2023-11-30 22:24:33 24 4
gpt4 key购买 nike

这是我的域名:

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; }
}

我想得到的是:

ForumThemes 列表以及每个 ForumTheme 的前 5 个 ForumMessages

是否可以在 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; }
}

所以一个 channel 有很多类别,一个类别有很多文章。

我想在这里做的是为每个 channel 获取 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; }
}
}

获取 channel 的查询非常简单(我们只显示其中包含活跃文章的 channel ):

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();

上面的查询为我提供了包含活跃文章的 channel 列表。现在我将自己获取文章:

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 问题。我觉得使用 future 我可以使用较少的往返行程来做到这一点。我还不太熟悉 NHibernate。是否有可能通过一次往返和 hydrate DTO 获得所有内容?在 QueryOver 中使用类似 ROW_NUMBER() OVER (PARTITION BY....) 的东西?我不想使用 HQL 或原始 SQL。

最佳答案

使用 2 次往返

var themes = session.Query<ForumTheme>().Select(t => new ThemeDto(t.Name)).List();

var topMessages = new List<IEnumerable<string>>(themse.Count);

foreach(var theme in themes)
{
var query = from message in session.Query<ForumMessage>()
from topic in message.Topics
from t in topic.Themes
where t.Name == theme.Name
orderby message.DatePosted desc
select message;
topMessages.Add(query.Take(5).ToFuture());
}

for(int i = 0;i < topMessages.Count; i++)
{
themes.TopMessages = topMessages[i].ToList();
}

return themes;

第二个场景

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)
)
.TransformUsing(Transformers.AliasToBean<ChannelDto.ArticleDto>());
}

// execute all subqueries at once through iterating one
channels[0].Articles.Any();

关于c# - NHibernate 每组前 N 行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12747573/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com