我有这些课程:
public class WallPost
{
public long WallPostId { get; set; }
[Required]
public long UserId { get; set; }
[Required]
public long WallUserId { get; set; }
[Required]
public string PostText { get; set; }
public DateTime CreatedOn { get; set; }
public virtual User WallUser { get; set; }
public virtual User User { get; set; }
public virtual ICollection<WallPostReply> WallPostReplies { get; set; }
}
public class WallPostReply
{
[Key]
public long ReplyId { get; set; }
[Required]
public long UserId { get; set; }
[Required]
public long WallPostId { get; set; }
[Required]
public string ReplyText { get; set; }
[Required]
public DateTime CreatedOn { get; set; }
public virtual WallPost WallPost { get; set; }
public virtual User User { get; set; }
}
在一种方法中,我获得了按CreatedOn排序的所有墙贴:
public IEnumerable<WallPost> GetMorePosts(long wallUserId, int pageNumber, bool showOnlyMyPosts)
{
var wallUser = _db.Users.Where(x => x.UserId == wallUserId).FirstOrDefault();
var postEntries = wallUser.MyWallPosts.Where(x => x.UserId == wallUser.UserId || showOnlyMyPosts == false).OrderByDescending(x => x.CreatedOn)
.Skip(5 * pageNumber).Take(5);
return postEntries;
}
我想要做的是获取按CreatedOn排序的WallPostReplies子实体,如何在同一个查询中编写它?
答案 0 :(得分:2)
首先,您的第二个查询是linq-to-objects,而不是linq-to-entities - 它将始终加载所有用户的帖子,并在您的应用程序服务器上进行过滤和排序。接下来,您不会显式加载回复,因此一旦您开始浏览它们,您将为每个帖子设置单独的延迟加载查询=&gt; N + 1问题。
使用linq-to-entities加载数据时,无法直接对子实体进行排序。您必须将投影用于匿名类型:
var query = _db.WallPosts
.Where(x => x.UserId == userId)
.OrderByDescending(x => x.CreatedOn)
.Skip(5 * pageNumber)
.Take(5);
.Select(x => new
{
Post = x,
Replies = x.WallPostReplies.OrderBy(y => y.CreatedOn)
});
再试一次:您无法从linq-to-entities获取具有已排序相关实体(WallPosts
)的WallReplies
个实例。您必须在linq-to-objects中对WallPosts
进行投影:
IEnumerable<WallPosts> posts = query.AsEnumerable()
.Select(x => new WallPost
{
WallPostId = x.Post.WallPostId,
UserId = x.Post.UserId,
WallUserId = x.Post.WallUserId,
PostText = x.Post.PostText,
CreatedOn = x.Post.CreatedOn,
Replies = x.Replies
});
答案 1 :(得分:1)
我有一个类似的问题.. 如果我理解你的话,你首先需要一个帖子列表,然后为每个帖子想要一份回复列表吗?
首先我们得到有问题的帖子......
//gets posts ...
public IEnumerable<WallPost> GetMorePosts(long wallUserId, int pageNumber, bool showOnlyMyPosts) {
WallUser wallUser = _db.Users.Where(x => x.UserId == wallUserId).FirstOrDefault() as WallUser;
IEnumerable<WallPost> results =
(from post in wallUser.MyWallPosts where post.UserId == wallUser.UserId showOnlyMyPosts == false order by post.CreatedOn descending)
.Skip(5 * pageNumber)
.Take(5);
return results.ToList();
}
然后我们得到回复......
// gets replies
IEnumerable<WallPost> posts = GetMorePosts(userid, pageNo, showonlyMine);
foreach(WallPost post in posts)
{
IEnumerable<WallPostReply> replies = (from reply in post.WallPostReplies order by reply.CreatedOn select reply).ToList();
// do something with post and the order list of replies
}
简而言之......我的建议......不要试图立刻做太多事!