Фильтрация по двум разным полям на основе списка - PullRequest
0 голосов
/ 26 января 2019

Конечная цель - иметь бесконечную прокрутку, показывающую только те элементы, которые попадают в пользовательские настройки. В настоящее время бесконечная часть еще не установлена, но, просматривая это, пожалуйста, помните о будущей цели на случай, если это повлияет на «лучший» способ достижения этой цели. Это проект ASP.NET Core.

У каждого предмета есть индикаторы местоположения и категории, и хотя сейчас я хотел бы углубиться в два, я просто делаю один уровень. Поэтому вместо того, чтобы делать страну и штат, я просто делаю страну. Чтобы добиться этого, мне нужен способ для пользователя: 1) указать свои предпочтения, 2) пометить элементы этой статистикой и 3) отфильтровать элементы, которые не соответствуют ни местоположению, ни категории.

1) Чтобы отметить настройки, мы используем bool на пользовательской модели:

public bool Country1 { get; set; }
public bool Country2 { get; set; }
…
public bool Cat1_1 { get; set; }
public bool Cat1_2 { get; set; }
…

2) Чтобы пометить элементы с такой статистикой на модели форума:

public int ForumCat1 { get; set; }
public int? ForumCat2 { get; set; }
…
public int? ForumCountry { get; set; }
public int? ForumState { get; set; }
…

3) Чтобы отфильтровать элементы, которые не совпадают в коде, мы используем это:

public IList<Forum> ForumPosts { get; set; }

public async Task OnGetAsync()
  {
    var user = await _userManager.GetUserAsync(User);

    var countryFilters = new List<int>();
    var cat1Filters = new List<int>();

    if (user.Country1) { countryFilters.Add(1); }
    if (user.Country2) { countryFilters.Add(2); }
    ….
    if (user.Cat1_1) { cat1Filters.Add(1); }
    if (user.Cat1_2) { cat1Filters.Add(2); }
    …
    var countryList = _appDbContext.Country.ToList();
    var cat1List = _appDbContext.Cat1.ToList();

    var forumPosts =  _appDbContext.Forum.ToList();
    ForumPosts = new List<Forum>();

    foreach (var countryId in countryFilters)
       {                
          foreach (var cat1Id in cat1Filters)
            {
              var forums = _appDbContext.Forum.Where(c => c.ForumCat1 == cat1Id && c.ForumCountry==countryId).ToList();
              foreach (var post in forums)
                {
                            ForumPosts.Add(post);       
                 }
              }
        }
  }

Хотя это работает, мне это кажется неэффективным. Мне кажется, что я должен быть в состоянии сделать что-то вроде:

For each (var post in forumPosts)
  {
    If countryFilter.contains(forumcountry) && cat1Filter.contains(forumCat1)
       {
        ForumPosts.Add(post)
       }
  }

Это не работает, или, по крайней мере, я не могу заставить его работать. Существует также проблема сохранения списка / коллекции в базе данных и необходимости создавать ее «на лету» для каждого запроса, но я не вижу в этом такой большой нагрузки, как циклический просмотр базы данных 8 раз для применения фильтрации, так что Меня больше интересует, если кто-нибудь знает более эффективный способ добиться этого?

По предложению Лукаша это работает и намного чище / эффективнее. Спасибо!

    var forumMatches = _appDbContext.Forum.Where(c => countryFilters.Contains(c.ForumCountry) && cat1Filters.Contains(c.ForumCat1)).AsEnumerable();
    ForumPosts = new List<Forum>();
    ForumPosts.AddRange(forumMatches);

Ответы [ 2 ]

0 голосов
/ 28 января 2019

@ Coveny Возможно, вы захотите вызвать .AsQueryable() вместо .ToList() на вашем countryFilters & cat1Filters. Возможно, вы столкнетесь с влиянием на производительность, если ваши коллекции слишком велики для повторения в памяти.

Взгляни на это Различия между IQueryable, List, IEnumerator?

0 голосов
/ 26 января 2019

Надеюсь, это то, что вы хотите:)

_appDbContext.Forum.Where(c => countryFilters.Contains(c.ForumCat1) && cat1Filters.Contains(c.ForumCountry))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...