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

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

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

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

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

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

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

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

Ответы на вопрос(2)

Решение Вопроса

ИзВот, это какой-то 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.Contains ... никто не переводит это. Используйте список (T) вместо.Для сервера sql действует ограничение на количество параметров. Это примерно 2000 параметров (выше, но ниже 2500). Если вам нужно использовать более 2000 тегов, вы должны искать другое решение.Я написал это без инструментов, после полуночи. Это, вероятно, не идеально.

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

List<string> searchTags = ...

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

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

 Tigraine21 янв. 2009 г., 22:35
Я только добавил пояснение к ответу и постараюсь .. Я думал о Intersecct, .. но не последовал там.

Ваш ответ на вопрос