2009-01-21 42 views
0

我挣扎了一下这里,所以我想为什么不问:通过标签选择的项目进行搜索时多个标签

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

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

我只是可以通过所有的标签,并做IQueryable.Where(p => p.Tags.Contains(currentTag),但这不会很好地扩展与许多标签作为输入,我也有这种感觉可里面的LinQ做

希望任何人有一个想法

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

问候Daniel/Tigraine

回答

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; 
} 

几个注意事项适用:

  • 列表(T)。载有由LinqToSql翻译,但LinqToEntities不会翻译。你将会得到一个运行时异常。
  • IList.Contains ...没有人翻译。改用列表(T)。
  • 对于sql server有一个参数计数限制有效。它大约有2000个参数(更高但低于2500)。如果您需要使用超过2000个标签,则应寻求不同的解决方案。
  • 我在午夜之后不用工具写了这个。这可能不完美。
0

不知道我真的明白你在问什么,但也许下面的东西会起作用。

List<string> searchTags = ... 

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

这应该给你一组,其中标签的列表包含项目中的至少一个在searchTags

+0

我刚刚给答案添加了一个说明,并会尝试..我想到Intersecct,但没有跟进。 – Tigraine 2009-01-21 21:35:24