Прежде всего, никогда не используйте Count (), если вам действительно не нужно точно знать, сколько элементов существует.Использование Count () для проверки пустого набора может потребовать обхода всего набора данных.Это критично для производительности, когда размер вашего набора данных превышает несколько элементов.Используйте!.Any () вместо .Count () == 0, .Any () вместо .Count ()> 0.
Далее, ваш тест NOT IN в исходном SQL звучит как операция установки разности.В LINQ это представлено .Except () A.Except (B) возвращает все элементы A, которые не найдены в B.
Меня немного смущает описание вашей проблемы.В тексте вы говорите, что хотите найти все продукты, которые имеют все атрибуты, найденные в списке FilterSpec.Но в обоих примерах кода вы используете NOT IN или тестируете на Contains, возвращая пустой результат, который, кажется, работает в направлении, противоположном текстовому описанию.
Если вы пытаетесь найти всепродукты, которые имеют все атрибуты, найденные в списке FilterSpec, тогда вы ищете эквивалентность набора.
Если элементы в ваших атрибутах и в списке их фильтров всегда перечислены в определенном порядке, то вы можете использовать Linq.SequenceEqual () функция.Я предполагаю, что ваши атрибуты не упорядочены, поэтому .SequenceEqual () не является правильным решением.
Чтобы проверить два набора значений A и B на эквивалентность, не зависящую от порядка, вы можете проверить на A.Except(B) пусто и B. Кроме (A) пусто.Используйте!.Any () для проверки на пустое.Первый говорит, что все в A можно найти в B, а второй говорит, что все в B можно найти в A. Что еще там есть?Ничего, поэтому два набора должны содержать абсолютно одинаковые элементы.
Попробуйте что-то вроде этого (не проверено):
var query = from p in Products
where !p.NpProductSpecificationAttributes.Except(filters).Any() &&
!filters.Except(p.NpProductSpecificationAttributes).Any()
select p;
Вероятно, вы можете получить лучшую производительность, используя HashSet, если толькочтобы уменьшить количество раз, хэш-наборы должны быть созданы внутри с помощью выражения выше.В приведенном ниже коде предполагается, что в списке фильтров и в атрибутах продукта нет повторяющихся элементов.Если ваш SpecificationAttributeOptionId не является примитивным типом (string, int), вам также может потребоваться указать средство сравнения на равенство.
var filterset = new HashSet<filteritemtype>(filters);
var query = from p in Products
where filterset.SetEquals(new HashSet<itemtype>(p.NpProductSpecificationAttributes))
select p;