Проблемы с Linq для сложного запроса

#c# #linq #entity-framework-core

#c# #linq #entity-framework-core

Вопрос:

У меня есть список пользователей, и у каждого пользователя есть список хэштегов.

В моем приложении я предоставляю способ поиска результатов по хэштегам.

В моем api я разделяю строку поиска, чтобы получить каждый хэштег отдельно, и то, что я пытаюсь получить, это:

Сущность пользователя, количество общих хэштегов и связанных хэштегов.

Например:

Мои классы, как показано ниже:

     public class UserDto
    {
        public List<HashtagDto> Hashtags { get; set; }

    }

    public class HashtagDto
    {
        string name { get; set; }

    }

    public class UserHashtagSearchResultDto
    {
        public UserDto UserFk { get; set; }

        public int CountResults { get; set; }

        public List<HashtagDto> HashtagsFk { get; set; }
    }
  

Мой запрос:

 if (searchText.IsNullOrEmpty())
            return null;

        var splits = searchText.Split(new string[] { " " }, System.StringSplitOptions.RemoveEmptyEntries);
        
        List<string> hashes = HashtagHelper.ToHashkeys(splits);

        if (hashes != null amp;amp; hashes.Count() > 0)
        {
            User.GetUsers().Include(h => h.Hashtags).Where(s => hashes.Contains(....).Select((hs) =>
             {
                 return new UserHashtagSearchResultDto
                 {

                 }
            });
        }
  

Ввод будет следующим: running swimming

Вывод будет:

Список

Пример:

Result1 { UserFk=User1

         CountResults=2 (the two hashtags of this user exists in the hashtag repository)

        HashtagsFk=List<Hashtag>{hashtag1, hashtag2}; // (swimming and running}
    }
  

Результат1
{
UserFk=User2

         CountResults=1 (only the hashtag swimming existsin the hashtag repository)

        HashtagsFk=List<Hashtag>{hashtag1}; // (swimming)
    }
  

Я не вижу, как это сделать с помощью linq.

Комментарии:

1. Почему вы должны использовать LINQ? Вы хотите сказать, что у вас есть рабочая версия, отличная от LINQ?

2. Нет, я этого не делал, но через foreach я мог это сделать. Я думаю, что linq должен быть более производительным. И было бы проще в коде.

3. LINQ может быть короче, но есть большая вероятность, что он будет менее производительным, чем больше. Это сильно зависит от того, как это делается (как и все остальное), но LINQ — это молоток, и не каждая проблема — гвоздь. С помощью циклов / словарей, которые вы создаете сами, вы можете точно видеть, что делается и где. С LINQ вам может потребоваться выполнить дополнительные шаги, чтобы заставить его работать, и то, как именно реализованы методы LINQ, не очевидно, поэтому, если вы хотите быть уверенным в том, как версия LINQ что-то делает, вам нужно точно знать, как LINQ выполняет то, что он делает для каждой операции

4. Не могли бы вы привести пример ввода и вывода? Может быть, поделитесь своим рабочим foreach?

Ответ №1:

Хорошо, это ответ на мой вопрос.

   var userCommon = _userRepository.GetAll().Include(h => h.HashtagUsers).ThenInclude(h => h.HashtagFk)
                 .Where(s => hashes.Intersect(s.HashtagUsers.Select(h => h.HashtagFk.Code).AsEnumerable()).Count() > 0);

            userCommon.ForEach(res =>
            {
                var result = new HashtagResultSearchDto();
                result.UserFk = ObjectMapper.Map<UserDto>(res);

                var d = res.HashtagUsers.AsQueryable().Select(h => h.HashtagFk);

                result.CountResult = result.Hashtags.Count();
                result.UserId = res.Id;

                hashtagResultSearchDtos.Add(result);
            });