Search code examples
c#entity-frameworklinqjoincontains

Entity Framework Linq IQueryable does not contain a definition for Contains


I have the following (working) query

return _context.SubCategories
            .Join(_context.CategoryLinks,
             sc => sc.ID,
             cl => cl.SubCategoryID,
             (sc, cl) => new { SubCategory = sc, CategoryLinks = cl })
             .Where(x => x.CategoryLinks.CategoryID != CategoryID)
             .Select(x => x.SubCategory).Distinct();

But my problem is that it will return double records in the end as a subcategory can be linked to multiple categories.

So i.e. we are retrieving the subcategories that are linked to the category Cat_1. Sub_A is linked to Cat_1 but also to Cat_2, the query will filter out Sub_A from the result once as it is linked to Cat_1 in the CategoryLink table. But in the end Sub_A will still be part of the resultset as it's also linked to Cat_2

So I thought if I'd retrieve the subcategories first (see code below) and then filter out the ones that have already been used with contains it would solve my issue.

var test = _context.CategoryLinks.Where(x => x.CategoryID == CategoryID);

IQueryable<DM.SubCategory> aaa = _context.SubCategories
          .Join(_context.CategoryLinks,
          sc => sc.ID,
          cl => cl.SubCategoryID,
          (sc, cl) => new { SubCategory = sc, CategoryLinks = cl })
          .Where(x => x.CategoryLinks.CategoryID != CategoryID && !test.Contains(x.SubCategory.ID))
          .Select(x => x.SubCategory);

However I'm getting an error when I try to do test.Contains which is; IQueryable<CategoryLink> does not contain a definition for Contains and the best extension method overload ParallelEnumerable.Contains<Guid>(ParallelQuery<Guid>, Guid) requires a receiver of type ParallelQuery<Guid>

Why is it not allowing me to use contains in above query? I tried replacing var test with IQueryable< DM.CategoryLink> test but that didn't matter.


Solution

  • IQueryable<T>.Contains have two overloaded methods, and both do not accept arbitrary type. If you want to check whether item is in the collection, use IQueryable<T>.Any instead.

    From you code snippet, I guess that it might be test.Any(t => t.ID == t.Subcategory.ID)