A stored procedure is actually a good option, if not the best option, really. However, you can still achieve it with Contains
:
var articles = db.Articles.Where(m => tags.Any(t => m.Tags.Contains(t)));
What this does is basically iterate over the passed in tags and creates a query that tests whether Tags
is LIKE any of those. Bear in mind that because this is going to be a LIKE query that it's going to be sloooooowwwww, unless your Tags
column is indexed, which then also requires that be a defined length, rather than something like NVARCHAR(MAX).
Another potential issue is false matches. Let's say you have the tags, "Read" and "Reading", because this is a LIKE query, search for the "Read" tag, will return both. The only way around this, really, is to add a tag-delimiter to your data, for instance: "[Read],[Reading]". Then, you search instead of for "[Read]", instead of "Read", and you're guaranteed to only pull back the right one.
When I need to pack/unpack strings like this, I'll typically do something like:
public string Tags
{
get
{
return TagsList != null
? String.Join(",", TagsList.Select(tag => "[" + tag + "]"))
: null;
}
set
{
TagsList = !String.IsNullOrWhiteSpace(value)
? value.Replace("[", "").Replace("]", "").Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).ToList()
: new List<string>();
}
}
[NotMapped]
public List<string> TagsList { get; set; }
That looks fairly complicated, but all that's going on is that the setter is unpacking the list of tags on the delimiter, removing the phrase-delimiting characters I chose to use, [
and ]
. The getter packs the list back into a string with all that.
This allows you to then just work with TagsList
and the string version will be persisted automatically without having to think about it. However, when querying, you will still have to query on Tags
, since that is the actual database-backed property.