在Web应用程序中过滤产品

时间:2016-08-29 09:43:03

标签: c# sql asp.net sql-server linq

我有一个产品表,产品可以分配任意数量的过滤器规格 - 即颜色,类型等。分配给产品的过滤器值存储在查找表中。这些表格有点复杂,但我可以使用的一个简单示例如下:

Products
-----------------
ProdID | Code | Price
1      | A1   | 2.99
2      | B1   | 10.99
10     | F4   | 20.00


Filters
-----------------
FilterID | Name
1        | Black
2        | Blue
4        | Round
10       | Waterproof


ProductFilterLookup
-------------------
ProdID | FilterID
1      | 1
1      | 4
1      | 10
2      | 1
2      | 10
10     | 1

因此,如果用户选择的产品是黑色'和'防水' (FilterID' 1和10)预期结果将是ProdID 1和2,因为只有那些产品具有这两种过滤器。

产品可以分配任何过滤器。我希望得到所有产品,这些产品都包含一组选定的过滤器(意味着它具有所有过滤器值)。

我可以在LINQ或SQL中执行此操作,并且需要尽可能高效(性能明智)。

2 个答案:

答案 0 :(得分:1)

对于性能 - 你可以获得linq可能和sql一样快。只需要一个sql和一个linq并比较两者的解释计划。看看它为linq生成了什么sql。

你可以测试:

var neededFilters = new List<string> { "Black", "Waterproof" };

var result1 = (from p in products
               join pf in productFilterLookup on p.ProdID equals pf.ProdID
               join f in filters on pf.FilterID equals f.FilterID
               group f.Name by p into grouping
               where neededFilters.All(filter => grouping.Contains(filter))
               select grouping.Key).ToList();

var result = (from p in products
              join f in (from pf in productFilterLookup
                         join f in filters on pf.FilterID equals f.FilterID
                         select new { pf.ProdID, f.Name })
                         on p.ProdID equals f.ProdID into grouping
              where neededFilters.All(filter => grouping.Any(item => item.Name == filter))
              select p).ToList();

答案 1 :(得分:0)

@Simon

要回答您的问题,此SQL语句将为您提供帮助:

SELECT pfl.id, p.productid, p.code, p.price, f.filterid, f.name 
FROM 
    productfilterlookup pfl
INNER JOIN
    products p ON (pfl.productid = p.productid)
INNER JOIN
    filters f ON (pfl.filterid = f.filterid)
WHERE pfl.filterid = 1 OR pfl.filterid = 10;

这会输出一些像这样的输出:

+----+-----------+------+-------+----------+--------------+
| id | productid | code | price | filterid | name         |
+----+-----------+------+-------+----------+--------------+
|  1 |         1 | A1   |  2.99 |        1 | Black        |
|  3 |         1 | A1   |  2.99 |       10 | Waterproofed |
|  4 |         2 | B1   | 10.99 |        1 | Black        |
|  5 |         2 | B1   | 10.99 |       10 | Waterproofed |
|  6 |        10 | F4   | 20.00 |        1 | Black        |
+----+-----------+------+-------+----------+--------------+