2

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:

  1. Am I over complicating this and is there a simple Linq statement which accomplishes this or,
  2. Is this something for which I would should use predicate builder to set my criteria?
Matthew
  • 9,851
  • 4
  • 46
  • 77

1 Answers1

1

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();
Bas de Raad
  • 556
  • 1
  • 6
  • 15
  • I had to make some changes to my data model before I could fully test, but this seemed to accomplish what I was asking when I backed out my changes to test (I couldn't spend a lot of time at it). Thanks - helped me look up the right things to accomplish a few other tasks as well. – Matthew Feb 19 '13 at 17:31
  • Glad it helped. Btw, to answer question 2 (a bit): did you know System.Linq.Dynamic exists? Nice to use if you want to dynamically build linq queries – Bas de Raad Feb 19 '13 at 19:15