Множественный динамический запрос в Linq

#c# #sql-server #linq #dynamicquery #predicatebuilder

#c# #sql-сервер #linq #динамический запрос #predicatebuilder

Вопрос:

Прежде всего, я объясню структуру таблицы

 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
  

пользователь передает массив categoryid из пользовательского интерфейса, например {1,2,3}(cotton material with black or white color) , или {1,4,3} (cotton or linen material with black color) должен группироваться с идентификатором атрибута для достижения этой цели.

Я попробовал другой способ, используя contains, но не работает должным образом, если проверка каждого продукта по всем категориям с использованием пользовательских циклов работает нормально, но сравнение каждого продукта со всеми условиями вызывает проблемы с производительностью.

Есть ли какое-либо простое решение этой проблемы? Есть ли какое-либо решение с использованием Predicatebuilder в linq?

любые фрагменты кода о том, как добиться этого с помощью 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;
  

Комментарии:

1. Извлеките данные таблицы в cache памяти, тогда у вас будет лучшая производительность. Они называются таблицами EAV , которые имеют проблемы с производительностью при большом запросе.

2. Если есть какое-либо решение на основе запросов, я буду очень признателен

3. «Я пробовал другой способ, используя contains, но не работает должным образом» И каковы были эти попытки, вы не показали ни одного из них в своем вопросе. Почему эти попытки не сработали? Каков ваш конкретный вопрос здесь? «Есть ли простое решение» — это просто вопрос «да» или «нет»; какой вопрос программирования у вас здесь?

4. @Larnu Я не говорю о полном решении кода, если я получу какие-либо фрагменты и некоторую логику, которую я смогу выработать, спасибо..

5. @Larnu Я пробовал, проверьте мою правку

Ответ №1:

Очень сложно понять ваш вопрос, но я думаю, что понял идею. Выглядит неэффективно, но я обновлю ответ, когда найду лучшее решение.

 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)) amp;amp;
     p.ProductCatLinks.Any(l => colors.Contains(l.CategoryId))
   select p;
  

Комментарии:

1. Спасибо за помощь, но проблема здесь в том, что материала может быть несколько, а цветов также может быть несколько, можно сослаться на Amazon или какой-либо другой веб-сайт электронной коммерции, здесь происходит то же самое.

2. Обновленный ответ, который очевиден.