This can be done like this:
var query = _entityRepository.Entities.Select(e => e);
query = searchTags.Aggregate(query, (current, tag) => current.Where(e => e.Tags.Any(t => t.TagValue == tag)));
var result = query.ToList();
Question
I have the following entities:
[Table("Entities")]
public abstract class Entity {
public int EntityID { get; set; }
public string Description { get; set; }
public virtual ICollection<Tag> Tags { get; set; }
}
And the Tag Entity:
public class Tag {
public int TagID { get; set; }
public int EntityID { get; set; }
public string TagValue { get; set; }
}
As the above makes sort of clear Tags are not reused just stored as strings. This has made determining whether Entities share tags slightly more difficult (and slow).
I have a working search to return a list of entities in which the entities contain any of the tags:
List<string> searchTags = new List<String> {"test1", "test2"};
entities = (_entityRepository.Entities
.Where(o=>o.Tags.Any(f=>searchTags.Contains(f.TagValue)));
Now I also need to return a list of Entities which contain all of the tags in the list. As a non-property variable cannot be passed into a Contains method I cannot just reverse the order of the call with an all, but this is basically what I am trying to achieve:
entities = (_entityRepository.Entities
.Where(o=>o.Tags.All(f=>f.TagValue.Contains(searchTags)));
I think I have just hit the point where I need to correct the DB schema to re-use Tags which should provide a general performance benefit when filtering my entities on lists of Tags, but I still wanted to ask the following questions:
La solution
This can be done like this:
var query = _entityRepository.Entities.Select(e => e);
query = searchTags.Aggregate(query, (current, tag) => current.Where(e => e.Tags.Any(t => t.TagValue == tag)));
var result = query.ToList();