使用Lambda表达式的高级搜索

本文关键字:高级 搜索 表达式 Lambda 使用 | 更新日期: 2023-09-27 18:09:47

我想实现高级搜索在我的ASP。. NET MVC应用程序,用户可以选择1个或多个条件进行产品搜索。

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

这是我到目前为止看到的

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();

我在ProductColor表之间有一个多对多关系,ProductColor是连接它们的表。对于Product, ProductSize, Size表也是如此。

代码与SizePrice Range一起完美地工作。Color的问题,因为.Any()在找到第一个Product时返回。如果有多个Product,它只返回第一个。

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

我搜索了很多,并且知道我可以动态地构建Where子句,但是我认为这对于我的要求来说工作量太大了。如果有一个简单的解决办法,我将非常高兴。

编辑

我删除了@Jeroen建议的working-as-wanted代码,并留下了我想要修复的代码。

我修复了它,感谢组合@jason和@Marlon的答案。我将把解放在另一个答案中。我只想了解两点:

  • 为什么只有当我基于产品查询时才能正常工作?
  • 为什么' . distinct() '没有任何作用,而我得到了重复的产品。

使用Lambda表达式的高级搜索

请尝试一下。当调用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();

尝试将您的查询基于Product,而不是ProductSize:(您没有说,所以我假设Size和Price在ProductSize对象中)。

var query = db.Product.AsQueryable();
if (string.IsNullOrEmpty(ProductColorId) == false)
    query = query.Where(product => product.ProductColors.Where(a => a.ColorID == IntColorId).Any());
if (string.IsNullOrEmpty(SizeId) == false)
    query = query.Where(product => product.Sizes.Where(s => s.Size_Id == IntSizeId));
(...)
var ProductSizeList = query
    .Select(product => product.ProductID)
    .Distinct()
    .ToList();

我更喜欢Jason W的方法,而不是将所有内容放在一个查询中,因为在查询中间的最后一个"或"会忽略数据库中的任何索引。

我就是这么做的

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();

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