Я пытаюсь внедрить систему тегов с каркасом сущностей С#. Я не могу получить запрос, требуемый для случая, когда ожидаются два или более тега для возврата результата. У меня много отношений (только FKs, DB), и я пытаюсь получить объект, когда все выбранные теги существуют. Object - LookupTable - Атрибуты. Я разбираю выбранные теги в списке, а затем пытаюсь получить только те объекты, для которых присутствуют все теги в этом списке. По-видимому, это приводит к тому, что я ожидаю от оператора "Любой", а не от "Все".
List<string> intersectTags = new List<string>();
foreach (object i in ef.objects.Where(o => o.Attributes.All(attribute =>
intersectTags.Contains(attribute.AttributeNK))))
Обновление. Также необходимо получить экземпляры, где ef.Object имеет больше тегов, чем intersectTags. Фильтрация для экземпляров, где intersectTags является подмножеством Object.Attributes.
Ваш код не работает, если ваши атрибуты являются подмножеством выбранных тегов.
Если вы ищете совпадение, когда intersectTags является подмножеством o.Attributes, попробуйте изменить регистр.
К сожалению, Linq to Entity не поддерживает такой синтаксис, нам нужен ToList()
для загрузки объектов и выполнения Linq To Objects.
Он должен работать, но есть последствия для производительности (я опубликую обновление, если у меня есть лучшее решение):
List<string> intersectTags = new List<string>();
foreach (object i in ef.objects.ToList().Where(intersectTags.All(tags =>
o.Attributes.Any(attribute => attribute.AttributeNK == tags))))
Я не знаю, хорошо ли я понял, если так, я могу дать решение в простом SQL. Вы должны искать все записи, содержащие один из запрошенных тегов, а затем группировать их с помощью productId с условием HAVING COUNT равным количеству передаваемых вами тегов.
SELECT ProductId FROM ProductTag
WHERE TagId IN (2,3,4)
GROUP BY ProductId
HAVING COUNT(*) = 3
Вот демо:
http://sqlfiddle.com/#!3/dd4023/3
Извините, в настоящее время я не могу дать вам реализацию в EF (у меня нет Visual Studio), я сделал что-то подобное для LINQ TO SQL и использует класс PredicateBuilder, вы можете найти его здесь:
http://www.codeproject.com/Articles/36178/How-to-manage-product-options-with-different-price
Paolo