C# 使用Lambda表达式的高级搜索

C# 使用Lambda表达式的高级搜索,c#,lambda,C#,Lambda,我想在我的ASP.NET MVC应用程序中实现高级搜索,用户可以在其中为产品搜索选择一个或多个条件 假设我有这些标准:颜色、尺寸、价格范围 这是我到现在为止所能做的 ProductSizeList = db.ProductSizes.Where(ProductSize => (string.IsNullOrEmpty(ProductColorId) || ProductSize.Product.ProductColors.Where(a => a.ColorID == Int

我想在我的ASP.NET MVC应用程序中实现高级搜索,用户可以在其中为产品搜索选择一个或多个条件

假设我有这些标准:颜色、尺寸、价格范围

这是我到现在为止所能做的

ProductSizeList = db.ProductSizes.Where(ProductSize =>
    (string.IsNullOrEmpty(ProductColorId) || ProductSize.Product.ProductColors.Where(a => a.ColorID == IntColorId).Any())
    ).GroupBy(x => x.ProductID).Select(Grouped => Grouped.FirstOrDefault()).ToList();
我在
Product
Color
表之间有一个多对多的关系,而
ProductColor
是链接它们的一个。与
产品
产品尺寸
尺寸
表格相同

该代码与
尺寸
价格范围
完美配合。
颜色的问题,因为
.Any()
在找到第一个
产品时返回。如果有多个
产品
,则只返回第一个

所以,我想知道是否有另一种方法,或者另一种方法可以获得所有指定颜色的产品

我搜索了很多,知道我可以动态构建Where子句,但我认为这对于我的需求来说太多了。如果有一个简单的解决办法,我会非常高兴

编辑

我删除了@Jeroen建议的“按需工作”代码,留下了我想要修复的代码

已解决

我修复了它,多亏了@jason和@Marlon答案的组合。我将把解决方案放在一个单独的答案中。我只想了解两点:

  • 为什么只有当我根据产品进行查询时,它才能正常工作
  • 为什么“.Distinct()”没有做任何事情,我得到了重复的产品

    • 请试试这个。当调用
      ToList
      时,它使用IQueryable可以让您在对数据库执行之前更轻松地构造条件

      var query = db.ProductSizes.AsQueryable();
      if (string.IsNullOrEmpty(ProductColorId) == false)
          query = query.Where(ProductSize => ProductSize.Product.ProductColors.Any(a => a.ColorID == IntColorId))
      if (string.IsNullOrEmpty(SizeId) == false)
          query = query.Where(ProductSize => ProductSize.Size.Id == IntSizeId);
      if (string.IsNullOrEmpty(From) == false)
          query = query.Where(ProductSize => ProductSize.Price >= DecimalFrom);
      if (string.IsNullOrEmpty(To) == false)
          query = query.Where(ProductSize => ProductSize.Price <= DecimalTo);
      var ProductSizeList = query
          .Select(ProductSize => ProductSize.ProductID)
          .Distinct()
          .ToList();
      
      var query=db.ProductSizes.AsQueryable();
      if(string.IsNullOrEmpty(ProductColorId)==false)
      query=query.Where(ProductSize=>ProductSize.Product.ProductColors.Any(a=>a.ColorID==IntColorId))
      if(string.IsNullOrEmpty(SizeId)==false)
      query=query.Where(ProductSize=>ProductSize.Size.Id==IntSizeId);
      if(string.IsNullOrEmpty(From)==false)
      query=query.Where(ProductSize=>ProductSize.Price>=DecimalFrom);
      if(string.IsNullOrEmpty(To)==false)
      query=query.Where(ProductSize=>ProductSize.Price-ProductSize.ProductID)
      .Distinct()
      .ToList();
      
      尝试将查询基于Product,而不是ProductSize:(您没有说,所以我假设大小和价格在ProductSize对象中)


      我喜欢Jason W的方法,而不是把所有的东西放在一个查询中,因为在最后一个查询中的“或”会忽略数据库中的任何索引。

      < P>这对我来说是有效的。
      var query = db.Products.AsQueryable();
      if (string.IsNullOrEmpty(ProductColorId) == false)
          query = query.Where(Product => Product.ProductColors.Any(a => a.ColorID == IntColorId));
      if (string.IsNullOrEmpty(SizeId) == false)
          query = query.Where(Product => Product.ProductSizes.Any(a => a.SizeID == IntSizeId));
      if (string.IsNullOrEmpty(From) == false)
          query = query.Where(Product => Product.ProductSizes.Any(a => a.Price >= DecimalFrom));
      if (string.IsNullOrEmpty(To) == false)
          query = query.Where(Product => Product.ProductSizes.Any(a => a.Price <= DecimalTo));
      var ProductsList = query
          .Select(ProductSize => ProductSize)
          .GroupBy(x => x.id).Select(Grouped => Grouped.FirstOrDefault())
          .ToList();
      
      var query=db.Products.AsQueryable();
      if(string.IsNullOrEmpty(ProductColorId)==false)
      query=query.Where(Product=>Product.ProductColors.Any(a=>a.ColorID==IntColorId));
      if(string.IsNullOrEmpty(SizeId)==false)
      query=query.Where(Product=>Product.productsize.Any(a=>a.SizeID==IntSizeId));
      if(string.IsNullOrEmpty(From)==false)
      query=query.Where(Product=>Product.productsize.Any(a=>a.Price>=DecimalFrom));
      if(string.IsNullOrEmpty(To)==false)
      query=query.Where(Product=>Product.ProductSize.Any)(a=>a.Price-ProductSize)
      .GroupBy(x=>x.id)。选择(Grouped=>Grouped.FirstOrDefault())
      .ToList();
      

      我的查询基于
      Product
      ,并使用
      GroupBy
      删除重复的结果,而不是
      Distinct

      您可能应该查看谓词()并可能链接它们。()如果您将代码缩减到实际的lambda(部分),这会有所帮助您遇到了问题,并且包含了一些最小的设置代码来重新处理问题。目前我觉得有很多代码位分散了您实际遇到的问题的注意力。我猜您不是通过调用Any()来过滤结果,而是在这里:Grouped.FirstOrDefault()。顺便说一句,您可以使用谓词直接调用Any,而不使用Where子句:Any(a=>a.ColorID==IntColorId)@firelkazar此代码放弃重复的结果
      GroupBy(x=>x.ProductID)。选择(Grouped=>Grouped.FirstOrDefault())
      ,使用
      大小
      价格范围
      ,它将返回所有结果,不会重复。感谢
      .Any()
      部分。抱歉,但我不明白这与我的解决方案有什么不同。
      .Any()
      将在满足条件后返回,并且只返回第一个产品。
      .Any()
      此处仅当颜色链接到查询中也链接到ProductSize的产品时才返回true。它尊重与其他条件匹配的产品。可能不理想的结果是由于
      GroupBy
      中的
      FirstOrDefault
      或原始查询或查询中没有真正分离的From/to因为您有其他产品尺寸链接到您不希望使用匹配颜色的产品?如果看不到您的数据,很难猜测这里出了什么问题,但这种方法应该可以。我已经使用过很多次。抱歉,但我不知道这与我的解决方案有什么不同。
      .Any()
      将在满足条件后返回,并且只返回第一个产品。Any位于产品内部。Where,因此将为每个产品调用它。并且,基于产品实体的查询,您不需要有分组依据。
      var query = db.Products.AsQueryable();
      if (string.IsNullOrEmpty(ProductColorId) == false)
          query = query.Where(Product => Product.ProductColors.Any(a => a.ColorID == IntColorId));
      if (string.IsNullOrEmpty(SizeId) == false)
          query = query.Where(Product => Product.ProductSizes.Any(a => a.SizeID == IntSizeId));
      if (string.IsNullOrEmpty(From) == false)
          query = query.Where(Product => Product.ProductSizes.Any(a => a.Price >= DecimalFrom));
      if (string.IsNullOrEmpty(To) == false)
          query = query.Where(Product => Product.ProductSizes.Any(a => a.Price <= DecimalTo));
      var ProductsList = query
          .Select(ProductSize => ProductSize)
          .GroupBy(x => x.id).Select(Grouped => Grouped.FirstOrDefault())
          .ToList();