搜索多个标签时按标签选择项目

时间:2009-01-21 21:24:06

标签: .net linq

我在这里苦苦挣扎,所以我想为什么不问:

我系统中的每个实体都有一个标签列表(一个字符串列表),我希望能够一次搜索多个标签。

我有一个可以使用的IQueryable。每个实体都有一个名为Tags的IList,我的输入参数是IList。

我只是可以浏览所有标签并执行IQueryable.Where(p => p.Tags.Contains(currentTag),但这不会很好地扩展很多标签作为输入,而且我感觉这个可以在LinQ内完成。

希望任何人都有一个想法。

编辑:澄清问题: 我搜索一种方法,只从我的IQueryable中选择包含所有提供的参数标签(IList)的项目。

问候Daniel / Tigraine

2 个答案:

答案 0 :(得分:2)

here开始,这是一些适合您的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 ...没有人翻译过。请改用List(T)。
  • 对sql server有效的参数计数限制。它大约有2000个参数(更高,但低于2500)。如果您需要使用超过2000个标签,则应寻求其他解决方案。
  • 我在午夜之后没有工具就写下了这个。这可能并不完美。

答案 1 :(得分:0)

不确定我真的明白你在问什么,但也许以下内容会起作用。

List<string> searchTags = ...

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

这应该为您提供一组实体,其中标签列表至少包含searchTags

中的一个项目