如何从嵌套集合中获取最后 n 个元素

How do I take last n elements from nested collection

我正在为一个应用程序建立聊天,所以当用户登录时我需要向他们发送所有 'unseen' 消息,我正在使用 entityframework,我想 return只有最后 20 条看不见的消息。但是我的查询不起作用,目前我得到这个异常

Count must be a DbConstantExpression or a DbParameterReferenceExpression

我做错了什么?

List<ChatVM> unSeenChats = db.Chats.Where(chat => !chat.Seen)
            .Select(chat => new ChatVM
            {
                Id = chat.Id,
                IsAnnonymous = chat.IsAnnonymous,
                UserName = chat.UserName,
                Messages = chat.Messages
                    .OrderBy(x => x.DateTime)
                    .Skip(chat.Messages.Count - 20 > 0 
                        ? chat.Messages.Count - 20 
                        : 0)
                    .Take(20)
                    .Select(message => new MessageVM
                    {
                        Id = message.Id,
                        DateTime = message.DateTime,
                        Text = message.Text
                    }).ToList()
            }).ToList();

我的模型如下:

public class Chat
{
    ...
    public virtual ICollection<Message> Messages { get; set; }
}
public class Message
{
    ...
    public int ChatId { get; set; }
    public virtual Chat Chat { get; set; }
}
public class Entities : IdentityDbContext<ApplicationUser>
{
    ....
    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        ...
        modelBuilder.Entity<Message>()
            .HasRequired(p => p.Chat).WithMany(p => p.Messages).WillCascadeOnDelete(true);
    }
}

谢谢

我认为您不能在查询中使用 .Count(因此出现您所看到的错误)。无论如何,我认为您是从错误的角度看待这个问题。您可能应该使用 OrderByDescending 方法,然后从那里获取前 20 个帖子。

像这样:

List<ChatVM> unSeenChats = db.Chats.Where(chat => !chat.Seen)
            .Select(chat => new ChatVM
            {
                Id = chat.Id,
                IsAnnonymous = chat.IsAnnonymous,
                UserName = chat.UserName,
                Messages = chat.Messages
                    .OrderByDescending(x => x.DateTime)
                    .Take(20)
                    .Select(message => new MessageVM
                    {
                        Id = message.Id,
                        DateTime = message.DateTime,
                        Text = message.Text
                    }).ToList()
            }).ToList();