public async Task <List <MessageDto> > GetChatMessagesAsync(long chatId, long userId, Guid?navMessageId, List <AttachmentType> attachmentsTypes = null, bool direction = true, byte messagesLimit = 30) { if (!await loadChatsService.IsUserJoinedToChatAsync(chatId, userId).ConfigureAwait(false)) { throw new GetMessagesException("User does not have access to chat."); } using (MessengerDbContext context = contextFactory.Create()) { var messagesQuery = from message in context.Messages where message.ChatId == chatId && message.Deleted == false select message; if (!attachmentsTypes.IsNullOrEmpty()) { List <short> types = attachmentsTypes.Select(type => (short)type).ToList(); messagesQuery = messagesQuery.Where(opt => opt.Attachments.Any(attach => types.Contains(attach.Type))); } if (navMessageId != null) { MessageDto navigationMessage = (await GetMessagesByIdAsync( new List <Guid> { navMessageId.Value }, ConversationType.Chat, chatId, userId).ConfigureAwait(false)).FirstOrDefault(); if (navigationMessage != null) { if (direction) { messagesQuery = messagesQuery.Where(opt => opt.SendingTime < navigationMessage.SendingTime); } else { messagesQuery = messagesQuery.Where(opt => opt.SendingTime > navigationMessage.SendingTime); } } } if (direction) { messagesQuery = messagesQuery .OrderByDescending(message => message.SendingTime) .ThenByDescending(message => message.Id) .ThenByDescending(message => message.GlobalId); } else { messagesQuery = messagesQuery .OrderBy(message => message.SendingTime) .ThenBy(message => message.Id) .ThenBy(message => message.GlobalId); } var messages = await messagesQuery .AsNoTracking() .Include(message => message.Attachments) .Take(messagesLimit) .ToListAsync() .ConfigureAwait(false); return(MessageConverter.GetMessagesDto(messages)); } }