Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to query ICollection?

I have two models, where both of them include an ICollection<T> object, something like this:

public class Business : ApplicationUser
{
    ...
    public virtual ICollection<Subcategory> Subcategories { get; set; }
    ...
}

public class Request
{
    ....
    public virtual ICollection<Subcategory> Subcategories { get; set; }
    ...
}

I want to query for the businesses and get the businesses whose subcategories match the ones in request (even one match is enough). I have something like this, which I wrote just as a sample, and of course it doesn't work (request is of type Request):

foreach (var subcategory in request.Subcategories)
{
    var businesses = db.Users
        .OfType<Business>()
        .Where(b => b.Subcategories
            .Where(s => s.SubcategoryName == subcategory.SubcategoryName));
}

So, for example, let's say we have two businesses, from which the first one has Football and Basketball as subcategories and the second one has Basketball and Tennis. Then, let's say our user selects both Football and Tennis subcategories, so my query should return both businesses, because first one includes Football, and the second one includes Tennis.

So, not every single subcategory should match, even one match is enough for accepting the business as a result. How can I achieve it? If you can provide the code I would be glad.

Here is also my subcategory model, in case you need it:

public class Subcategory
{
    public int SubcategoryID { get; set; }

    public string SubcategoryName { get; set; }
}
like image 769
tett Avatar asked Dec 14 '22 20:12

tett


1 Answers

Look at the signatures of your Linq methods. In particular, Where

Enumerable.Where<TSource> Method (IEnumerable<TSource>, Func<TSource, Boolean>)

expects a predicate that returns a boolean value. Where returns a collection, so you can't plug it into a Where clause expecting a Func that returns a boolean; that's not going to work.

What you probably need is something like this:

var businesses = db.Users.OfType<Business>()
    .Where(b => b.Subcategories
    .Any(s => s.SubcategoryName == subcategory.SubcategoryName));

Notice the use of Any. Any returns a boolean value, indicating whether or not a record was found matching your predicate s => s.SubcategoryName == subcategory.SubcategoryName

like image 177
Robert Harvey Avatar answered Jan 02 '23 02:01

Robert Harvey