Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
961 views
in Technique[技术] by (71.8m points)

.net - Select items by tag when searching multiple tags

I'm struggling a bit here so I thought why not ask:

Every entity in my system has a list of tags (a list of strings), and I want to be able to search for multiple tags at once.

I have a IQueryable to work with. Every Entity has a IList called Tags and my input parameter is a IList.

I simply could go through all tags and do IQueryable.Where(p => p.Tags.Contains(currentTag), but that would not scale very well with many tags as input, and also I have the feeling that this could be done inside LinQ.

Hope anyone has an Idea.

Edit: Clarification of question: I search for a way to only select Items from my IQueryable that contain ALL supplied parameter tags (of IList).

greetings Daniel / Tigraine

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

From here, this is some sql that will work for you:

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

Now the trick is getting Linq to produce it... Here's some LinqToSql code:

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

A few caveats apply:

  • List(T).Contains is translated by LinqToSql, but LinqToEntities will not translate it. You will instead get a runtime exception.
  • IList.Contains... nobody translates that. Use List(T) instead.
  • There is a parameter count limit in effect for sql server. It's approximately 2000 parameters (higher, but lower than 2500). If you need to use more than 2000 tags, you should seek a different solution.
  • I wrote this without tools, after midnight. It's probably not perfect.

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...