views:

55

answers:

3

I am just getting started with LINQ. I am creating an Entity Framework app that uses the canonical Post and Tag model. A Post contains an ID, Text, and Tags, and a Tag contains an ID, a Name, and Posts.

A previous thread on StackOverflow showed me how to query for a Post that matches all Tag objects (A and B and C) in a search list. But how would I query for a Post that matches any Tag (A or B or C) in the list? Thanks for your help.

+1  A: 

Stumbled over the answer right after I posted this question. PredicateBuilder to the rescue!

Here's my code, which uses PredicateBuilder. It is set up as an extension method:

public static IQueryable<Note> WhereContainsAnyTags(this IQueryable<Note> notes, IEnumerable<Tag> searchTags)
{
    // Initialize
    var predicate = PredicateBuilder.False<Note>();

    // Select Notes that contain any search Tags
    foreach (var searchTag in searchTags)
    {
        var tag = searchTag;
        predicate = predicate.Or(note => note.Tags.Any(t => t.Id == tag.Id));
    }

    // Set return value
    return notes.AsExpandable().Where(predicate);
}

And here is how I call the code:

searchResults = m_ViewModel.ObjectContext.Notes.WhereContainsAnyTags(m_ViewModel.SearchTags);
David Veeneman
A: 

Not sure if this would work or not, but worth a try anyway I guess if you are already using WhereIn.

var posts = context.Tags.WhereIn(tag => tag.Name, acceptableValues)
                        .SelectMany(t => t.Posts);

The WhereIn should give you all the tags that are part of the name, and the SelectMany should give you all the posts containing those tags.

NickLarsen
A: 

You could aslo do it like this with Entity SQL

var post = ctx.Posts.Where("it.Tags.Id IN (1,2,3)");
moi_meme