public async Task <List <MessageDto> > SearchMessagesAsync( string query, ConversationType?conversationType, long?conversationId, ConversationType?navConversationType, long?navConversationId, Guid?navMessageId, long?userId, int limit = 30) { using (MessengerDbContext context = contextFactory.Create()) { var messagesCondition = PredicateBuilder.New <Message>(); var messagesQuery = context.Messages.AsNoTracking(); ExpressionsHelper expressionsHelper = new ExpressionsHelper(); var messageExpression = expressionsHelper.GetMessageExpression(query); if (conversationType != null && conversationId != null) { if (userId != null && !await conversationsService.IsUserInConversationAsync(conversationType.Value, conversationId.Value, userId.Value).ConfigureAwait(false)) { return(new List <MessageDto>()); } switch (conversationType.Value) { case ConversationType.Dialog: messagesQuery = messagesQuery.Where(message => message.DialogId == conversationId); break; case ConversationType.Chat: messagesQuery = messagesQuery.Where(message => message.ChatId == conversationId); break; case ConversationType.Channel: messagesQuery = messagesQuery.Where(message => message.ChannelId == conversationId); break; } } else { if (userId != null) { var dialogsIds = await loadDialogsService.GetUserDialogsIdAsync(userId.Value).ConfigureAwait(false); var chatsIds = await loadChatsService.GetUserChatsIdAsync(userId.Value).ConfigureAwait(false); var channelsIds = await loadChannelsService.GetUserChannelsIdAsync(userId.Value).ConfigureAwait(false); messagesCondition = dialogsIds.Aggregate(messagesCondition, (current, value) => current.Or(option => option.DialogId == value).Expand()); messagesCondition = chatsIds.Aggregate(messagesCondition, (current, value) => current.Or(option => option.ChatId == value).Expand()); messagesCondition = channelsIds.Aggregate(messagesCondition, (current, value) => current.Or(option => option.ChannelId == value).Expand()); messagesQuery = messagesQuery.Where(messagesCondition); } } if (navConversationId != null && navConversationType != null && navMessageId != null) { var navMessage = (await GetMessagesByIdAsync( new List <Guid> { navMessageId.Value }, navConversationType.Value, navConversationId.Value, userId).ConfigureAwait(false)).FirstOrDefault(); if (navMessage != null) { messagesQuery = messagesQuery .Where(message => message.SendingTime <= navMessage.SendingTime && message.GlobalId != navMessage.GlobalId); } } var messages = await messagesQuery .Where(messageExpression) .Where(message => !message.Deleted && (message.ExpiredAt == null || message.ExpiredAt > DateTime.UtcNow.ToUnixTime())) .OrderByDescending(message => message.SendingTime) .Take(limit) .Include(message => message.Attachments) .ToListAsync() .ConfigureAwait(false); return(MessageConverter.GetMessagesDto(messages)); } }