根据列表按两个不同的字段进行过滤

时间:2019-01-26 05:09:31

标签: asp.net-core filter

最终目标是拥有一个无限滚动,仅显示属于用户首选项的项目。目前,还没有设置无限的部分,但是当您浏览此部分时,请牢记未来的目标,以免影响实现这一目标的“最佳”方式。该项目是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次来应用过滤那样大的开销,因此如果有人知道实现此目标的更有效方法,我会更感兴趣?

根据卢卡什(Lukáš)的建议,此方法有效且更加清洁/高效。谢谢!

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

2 个答案:

答案 0 :(得分:0)

我希望这就是你想要的:)

_appDbContext.Forum.Where(c => countryFilters.Contains(c.ForumCat1) && cat1Filters.Contains(c.ForumCountry))

答案 1 :(得分:0)

@Coveny您可能想在.AsQueryable().ToList()上调用countryFilters而不是cat1Filters,如果您的集合太大而无法迭代,那么可能会影响性能在内存中。

看看这个 Differences between IQueryable, List, IEnumerator?