#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. Обновленный ответ, который очевиден.