【问题标题】:Select items by tag when searching multiple tags搜索多个标签时按标签选择项目
【发布时间】:2025-11-30 14:10:01
【问题描述】:

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

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

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

我可以简单地遍历所有标签并执行 IQueryable.Where(p => p.Tags.Contains(currentTag),但是对于许多标签作为输入,这不会很好地扩展,而且我觉得这可以在 LinQ 中完成。

希望任何人有一个想法。

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

问候丹尼尔/蒂格莱尼

【问题讨论】:

    标签: .net linq


    【解决方案1】:

    来自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 个标签,则应寻求不同的解决方案。
    • 我在午夜之后在没有工具的情况下写了这篇文章。它可能并不完美。

    【讨论】:

      【解决方案2】:

      不确定我是否真的理解您的要求,但也许类似以下内容会起作用。

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

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

      【讨论】:

      • 我只是在答案中添加了一个澄清,并会尝试..我想过 Intersecct,.. 但没有跟进。