问题描述
首先,我将解释表结构
First table Attribute Second table Category
Id Name Id Name AttributeId(Foreign Key)
------------------ -----------------------------------------
1 Material 1 Cotton 1
2 Size 2 Black 3
3 Color 3 White 3
4 Linen 1
Third Table ProductCatLink
Id CategoryId(Fk Category table) ProductId(FK of Product Table)
-----------------------------------------------------------------------------
1 1 5
2 2 6
3 2 5
4 4 6
5 4 7
6 3 8
考虑用户选择材料棉和黑色和白色,结果必须为
Id CategoryId ProductId(ForeignKey of Product Table)
---------------------------------------------------------------
1 1 5
2 2 5
考虑用户选择棉麻材料以及黑色和白色,则结果必须为
Id CategoryId ProductId(ForeignKey of Product Table)
-------------------------------------------------------------------
1 1 5
2 4 6
3 2 5
4 1 6
用户从用户界面传递{1,2,3}(cotton material with black or white color)
或{1,4,3} (cotton or linen material with black color)
之类的categoryid数组必须与属性id一起分组才能实现。
如果尝试使用自定义循环检查具有所有类别的每个产品都可以,但是将每个产品与所有条件进行比较都会导致性能问题,那么我尝试使用包含方式但不能正常工作的其他方式。
有没有针对此问题的简单解决方案? 有没有在linq中使用Predicatebuilder的解决方案?
有关如何使用linq实现此目标的任何代码段都将很有帮助
我这样做是因为存在性能问题吗?
ExpressionStarter<Products> ProductPredicater(params int[] categories)
{
var predicate = PredicateBuilder.New<Products>();
var catwithAttributes = from cat in categories.AsEnumerable()
join pSubCat in
_productSubCat.GetAll().AsEnumerable()
on cat equals pSubCat.Id
select pSubCat;
var attributeids = catwithAttributes.GroupBy(m =>
m.AttributeId).Select(m => m.Key);
foreach (int keyword in attributeids)
{
var subcatlist = catwithAttributes.Where(m => m.AttributeId == keyword).Select(m => m.Id).ToList();
predicate = predicate.And(p => p.ProductCategoryLinkDetails.Any( l=> subcatlist.Contains(Convert.ToInt32(l.ProductSubCategory_Id))));
}
return predicate;
}
var result = from p in products.Get(ProductPredicater(input.ProductCategoryId),null,m => m.ProductCategoryLinkDetails) select p;
解决方法
很难理解您的问题,但是我想我知道。看起来性能不佳,但是找到更好的解决方案时我会更新答案。
var materials = new[] { 1 };
var colors = new[] { 2,3 };
var query = from p in db.Products
where
p.ProductCatLinks.Any(l => materials.Contains(l.CategoryId)) &&
p.ProductCatLinks.Any(l => colors.Contains(l.CategoryId))
select p;