【问题标题】:Using for loop on where() method在 where() 方法上使用 for 循环
【发布时间】:2020-10-28 10:45:49
【问题描述】:

所以我有一个搜索输入和复选框,当有输入时将值传递给控制器​​。我想使用这些值从数据库中取回一些东西。搜索输入是一个字符串,它可以正常工作。这是搜索输入的代码:

public async Task<ViewResult> Index(string searchString, List<int> checkedTypes)
{
    var products = from p in _db.Products select p;

    ViewData["CurrentFilter"] = searchString;
    
    if (!string.IsNullOrEmpty(searchString))
    {
        products = products.Where(p => p.Name.ToLower().Contains(searchString));
    }
    
    return View(products);
}

但是,复选框值存储在列表中。所以基本上我想和上面的代码一样,但是有一个列表。所以基本上一个想法是这样的:

if(checkedTypes != null)
{
    foreach (var i in checkedTypes)
    {
        products = products.Where(p => p.TypeId == i));
    }              
}

如果我像上面的代码那样做,我只会从循环中获取最后一个 (i)。我做的另一个解决方案是:

if(checkedTypes != null)
{
    var temp = new List<Product>();
    
    foreach (var i in checkedTypes)
    {
        temp.AddRange(products.Where(p => p.TypeId == i));
    }
    products = temp.AsQueryable();
}

但是当我这样做时,我得到了这个错误:

InvalidOperationException:源 IQueryable 的提供程序未实现 IAsyncQueryProvider。只有实现 IAsyncQueryProvider 的提供程序才能用于实体框架异步操作。

那么有人有我可以使用的解决方案吗?或者有没有更好的方法来处理控制器中的复选框?

【问题讨论】:

  • 请考虑反复添加products = products.Where(p =&gt; p.TypeId == i)); 会做什么。基本上你会说“我只想要 TypeId 10 的项目,然后我只想要 TypeId 11 的项目”。提示,此时不会有 11 的,只有 10 的,但最终结果是你不会得到任何东西,因为没有项目的 TypeId 为 10 11。它会 仅当checkedTypes 中只有 1 项时才起作用。

标签: c# .net-core checkbox


【解决方案1】:

假设您使用的是 EF Core(linq2db 也是如此) - 它支持使用本地集合进行翻译过滤,即Where(x =&gt; checkedTypes.Contains(x.SomeId))

如果您有“和”逻辑来过滤searchStringcheckedTypes,那么您可以有条件地添加Where 子句:

  if (!string.IsNullOrEmpty(searchString))
  {
       products = products.Where(p => p.Name.ToLower().Contains(searchString));
  }

  if(checkedTypes != null)
  {
       products = products.Where(p => checkedTypes.Contains(p.TypeId));    
  }

附言

您还应该能够将第一行更改为:

var products = _db.Products.AsQueryable();

【讨论】:

  • @TanveerBadar 没有原因 var 将是 DbSet 并且 OP 以后将无法将可查询分配给同一变量。
  • ' if (!string.IsNullOrEmpty(searchString)) { products = products.Where(p => p.Name.ToLower().Contains(searchString)); } if(checkedTypes != null) { products = products.Where(p => checkedTypes.Contains(p.TypeId)); @Guro Stron,先生,您太棒了。现在回想起来,我有点傻,为什么我没有想到这一点。但它现在有效。非常感谢
  • @zlatan114r 很乐意提供帮助!
猜你喜欢
  • 2017-04-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-06-16
  • 2016-02-25
  • 2014-01-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多