请教各位大佬,ToTree树型查询如何限制子列表的返回记录数呢? 返回
如题,我想实现一个读取文章评论的功能,其中Repiles是该条评论的回复信息列表(代码如下)。
为了减轻服务器负担,每条评论我想只读取该评论的前5条回复内容,我尝试在ToTree后面加Take方法,但是不起作用。.ToTree(...).Take(5);
请问大佬们,这个功能如何实现呢?
[SugarTable("comments")] public class CommentInfor { /// <summary> /// 评论编号 /// </summary> [SugarColumn(IsPrimaryKey = true, IsIdentity = true)] public long ID { get; set; } /// <summary> /// 评论人编号 /// </summary> public int UID { get; set; } /// <summary> /// 所属的评论编号(回复) /// </summary> public long ParentID { get; set; } /// <summary> /// 文章编号 /// </summary> public long ArticleID { get; set; } /// <summary> /// 评论内容 /// </summary> public string Content { get; set; } /// <summary> /// 评论回复列表 /// </summary> [SugarColumn(IsIgnore = true)] public List<CommentInfor> Replies { get; set; } } ///获取文章的评论列表 public static ListResult<CommentInfor> GetComments(int articleID) { var data = db.Queryable<CommentInfor>() .Where(i => i.ArticleID == articleID).Take(10) .ToTree(i => i.Replies, i => i.ParentID, 0); //此处返回了全部符合条件的记录,如何限制只返回前5条记录呢? return new ListResult<CommentInfor>(data); }
热忱回答(12)
-
fate sta VIP02024/2/6
级别不多 可以用导航查询
includes(it=>Child.Take(5).ToList(),it=>it.Child.Take(5).ToList(),it=>it.Child.Take(5).ToList())
.ToList();
0 回复 -
yookt VIP02024/2/6
@fate sta:谢谢大佬的回复,我之前是用的一对多导航查询,但导航查询有一个功能我一直实现不了。
CommentInfor中其实还有个字段Commenter(评论人的名称) 用了导航查询,是要读取另一张用户表里的字段值。用了导航查询好像就没有办法在子列表中再进行一对一导航了,完整代码如下:
[SugarTable("comments")] public class CommentInfor { /// <summary> /// 评论编号 /// </summary> [SugarColumn(IsPrimaryKey = true, IsIdentity = true)] public long ID { get; set; } /// <summary> /// 评论人编号 /// </summary> public int UID { get; set; } /// <summary> /// 所属的评论编号(回复) /// </summary> public long ParentID { get; set; } /// <summary> /// 文章编号 /// </summary> public long ArticleID { get; set; } /// <summary> /// 评论内容 /// </summary> public string Content { get; set; } /// <summary> /// 回复的目标用户编号 /// </summary> public int ReplyToUID { get; set; } /// <summary> /// 回复的目标用户昵称 /// </summary> [Navigate(NavigateType.OneToOne, nameof(ReplyToUID))] public string ReplyToUser { get; set; } /// <summary> /// 评论人昵称 /// </summary> [Navigate(NavigateType.OneToOne, nameof(UID))] public string Commenter { get; set; } /// <summary> /// 评论回复列表 /// </summary> [SugarColumn(IsIgnore = true)] public List<CommentInfor> Replies { get; set; } } ///获取文章的评论列表 public static ListResult<CommentInfor> GetComments(int articleID) { if (!db.ConfigQuery.Any())//保证只配置一次不能更新,该配置是全局静态存储 { db.ConfigQuery.SetTable<UserInfor>(it => it.UID, it => it.Nickname); } var data = db.Queryable<CommentInfor>().Select(i => new CommentInfor { UID = i.UID.SelectAll(), ReplyToUser = i.ReplyToUID > 0 ? i.ReplyToUID.GetConfigValue<UserInfor>() : null, Commenter = i.UID.GetConfigValue<UserInfor>() }) var data = db.Queryable<CommentInfor>() .Where(i => i.ArticleID == articleID).Take(10) .ToTree(i => i.Replies, i => i.ParentID, 0); //此处返回了全部符合条件的记录,如何限制只返回前5条记录呢? return new ListResult<CommentInfor>(data); }
0 回复 -
fate sta VIP02024/2/6
Select(xxx)
.MergeTable()
.Includes() 是可以这样的 你的DTO需要配置导航,并且DTO中配置导航的字段要有值
0 回复 -
yookt VIP02024/2/6
@fate sta:大佬,Select中的代码如何写呢?能否详细一点,万分感谢!
0 回复 -
fate sta VIP02024/2/7
var data = db.Queryable<
CommentInfor
>().Select(i => new CommentInfor
{
UID = i.UID.SelectAll(),
ReplyToUser = i.ReplyToUID > 0 ? i.ReplyToUID.GetConfigValue<
UserInfor
>() : null,
Commenter = i.UID.GetConfigValue<
UserInfor
>()
})
.MergeTable()
.Includes(x=>x.Child.Take(10).ToList(),x=>x.Child.Take(10).ToList(),x=>x.Child.Take(10).ToList())
.ToList();
0 回复 -
fate sta VIP02024/2/7
差不多这个意思
DTO配置好导航
0 回复 -
yookt VIP02024/2/7
@fate sta:谢谢大佬,您给的代码是可以实现限定读取条数,但是有个问题,我的DTO中是有通过UID读取用户昵称的配置的,Include后在Replies列表中用户昵称获取不到了,请问该如何修改呢?
0 回复 -
fate sta VIP02024/2/7
不就是这么写的吗?
0 回复 -
yookt VIP02024/2/7
@fate sta:
我的意思是Replies中也有commenter这个字段,需要通过配置查询来关联到用户名字段,而Replies是通过一对多导航查询出的数据
所以我想请教,在Includes方法中能否实现配置查询。我现在用的是笨办法,首先查询出评论列表,然后循环每个评论来分别读取相应的回复,但这样会多次读取数据库。
0 回复 -
fate sta VIP02024/2/7
@yookt:用导航就可以实现
0 回复 -
fate sta VIP02024/2/7
一对一导航
0 回复 -
fate sta VIP02024/2/7
不要想着联表了,返回一个对象就行了
0 回复