Выбирать элементы по тегу при поиске по нескольким тегам

Я тут немного борюсь, поэтому подумал, почему бы не спросить:

Каждый объект в моей системе имеет список тегов (список строк), и я хочу иметь возможность искать сразу несколько тегов.

У меня есть IQueryable для работы. У каждой сущности есть список IList с именем Tags, а мой входной параметр - это список IList.

Я просто мог бы пройти через все теги и сделать IQueryable.Where (p => p.Tags.Contains (currentTag), но это не очень хорошо масштабировалось бы со многими тегами в качестве входных данных, а также у меня есть ощущение, что это можно сделать внутри LinQ.

Надеюсь, у кого-нибудь есть идея.

Обновлено: уточнение вопроса: Я ищу способ выбрать только те элементы из моего IQueryable, которые содержат ВСЕ предоставленные теги параметров (из IList).

привет Даниил / Тигрень

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
0
337
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Не уверен, что я действительно понимаю, о чем вы спрашиваете, но, возможно, что-то вроде следующего сработает.

List<string> searchTags = ...

var query = db.MyEntity
              .Where( e => e.Tags.Intersect( searchTags ).Count() > 0 );

Это должно дать вам набор сущностей, где список тегов содержит хотя бы один из элементов в searchTags.

Я просто добавил пояснение к ответу и попробую .. Я думал о Intersecct, ... но не продолжил.

Tigraine 22.01.2009 00:35
Ответ принят как подходящий

Из здесь это какой-то sql, который вам подойдет:

SELECT entityID
FROM tags
WHERE tagID in (...) --taglist
GROUP BY entityID
HAVING COUNT(DISTINCT tagID) = ... --tagcount

Теперь уловка состоит в том, чтобы заставить Linq произвести его ... Вот код LinqToSql:

public List<int> GetEntityIds(List<int> tagIds)
{
  int tagCount = tagIds.Count;

  CustomDataContext myDC = new CustomDataContext();

  List<int> entityIds = myDC.Tags
    .Where(t => tagIds.Contains(t.TagId))
    .GroupBy(t => t.entityId)
    .Where(g => g.Select(t => t.TagId).Distinct().Count() == tagCount)
    .Select(g => g.Key)

  return entityIds;
}

Следует сделать несколько предостережений:

  • List (T) .Contains переводится LinqToSql, но LinqToEntities не переводит его. Вместо этого вы получите исключение во время выполнения.
  • IList.Содержит ... это никто не переводит. Вместо этого используйте Список (T).
  • Для sql server действует ограничение на количество параметров. Это примерно 2000 параметров (выше, но ниже 2500). Если вам нужно использовать более 2000 тегов, вам следует искать другое решение.
  • Я написал это без инструментов, после полуночи. Наверное, не идеально.

Другие вопросы по теме