我有一个产品表,产品可以分配任意数量的过滤器规格 - 即颜色,类型等。分配给产品的过滤器值存储在查找表中。这些表格有点复杂,但我可以使用的一个简单示例如下:
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中执行此操作,并且需要尽可能高效(性能明智)。
答案 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 |
+----+-----------+------+-------+----------+--------------+