Linq中的多个动态查询

问题描述

首先,我将解释表结构

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;