Matthew Peterson
Matthew Peterson

Reputation: 325

Entity Framework Linq Query to List - Error when using contains: Only primitive types, enumeration types and entity types are supported

I have many queries just like this one, but I can't figure out why this one is erroring. It seems like it has something to do with the parts of my where clause when I am doing the null check and then using Contains.

The error I am getting is:

Cannot compare elements of type 'System.Collections.Generic.IEnumerable`1[[System.Nullable`1[[System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]'. Only primitive types, enumeration types and entity types are supported.

And the code where it is thrown:

public static IEnumerable<Product> GetProducts(int? productDepartmentId = null, int? productCategoryId = null, IEnumerable<int?> productCategoryIds = null, IEnumerable<string> sections = null)
{
    using (var context = new AppContext())
    {
        var retList = (from obj in context.Products
                       where (productDepartmentId == null || obj.ProductDepartmentId == productDepartmentId) &&
                             (productCategoryId == null || obj.ProductCategoryId == productCategoryId) &&
                             (productCategoryIds == null || productCategoryIds.Contains(obj.ProductCategoryId)) &&
                             (sections == null || sections.Contains(obj.sections))
                       select obj).ToList();
        return retList;
    }
}

These are the lines that are making it error. I believe it doesn't like the null check:

(productCategoryIds == null || productCategoryIds.Contains(obj.productCategoryIds)) &&
(sections == null || sections.Contains(obj.Section))

Here is my call to the method (sections isn't being passed):

List<int?> categoryIds = new List<Int?>;
varList = ProductsDAL.GetProducts(productDepartmentId: productproductDeparmentId, 
                                  productCategoryId: productCategoryId, 
                                  productCategoryIds: categoryIds);

I have also tried passing in a List of type int.

Upvotes: 8

Views: 11471

Answers (1)

Dacker
Dacker

Reputation: 892

If it doesn't like the null check and you need it to be optional, you can do this:

List<int> productCategoryIdsTemp = new List<int>();
if (productCategoryIds != null) {
    productCategoryIdsTemp.AddRange(productCategoryIds.Where(id => id != null).Select(id => id.Value));
}
if (sections = null) { 
    sections = new List<string>();
}

And then in your Linq query use this:

(productCategoryIdsTemp.Count == 0 || productCategoryIdsTemp.Contains(obj.ProductCategoryId)) &&
(sections.Count == 0 || sections.Contains(obj.section)) &&

If your productCategoryIds wasn't an IEnumerable of nullable ints you could do the same as for sections. (Don't really understand how this needs to be supported instead of a list of int)

Upvotes: 4

Related Questions