简体   繁体   中英

Cannot get correct results from Linq query

I am trying to query my database using Linq. In short, my linq statement is not returning the data that I want and I am getting errors.

public class Product{
        [Key]
        public int id{get;set;}
        [Required]
        [MinLength(3)]
        public string Name{get;set;}
        [MinLength(10)]
        public string Description{get;set;}
        [Required]
        [Range(0, double.MaxValue)]
        public decimal Price{get;set;}
        public DateTime CreatedAt{get;set;} = DateTime.Now;
        public DateTime UpdatedAt{get;set;} = DateTime.Now;

        public List<ProductCategory> ProductCategories{get;set;}
    }

public class Category{
        [Key]
        public int id{get;set;}
        [Required]
        [MinLength(2)]
        public string Name{get;set;}
        public DateTime CreatedAt{get;set;} = DateTime.Now;
        public DateTime UpdatedAt{get;set;} = DateTime.Now;

        public List<ProductCategory> ProductCategories{get;set;}
    }

public class ProductCategory{
        [Key]
        public int id{get;set;}
        public int ProductId{get;set;}
        public int CategoryId{get;set;}

        public Product Product{get;set;}
        public Category Category{get;set;}
    }

#Variable used in troublesome code (in controller)
Product product = context.Products
                .Include(p => p.ProductCategories)
                .ThenInclude(pc => pc.Category)
                .FirstOrDefault(p => p.id == id);

#Troublesome code (in controller)
List<Category> categories = context.Categories
                .Include(c => c.ProductCategories)
                .ThenInclude(pc => pc.Product)
                .Where(c => c.ProductCategories.Select(pc => pc.Product) != product)
                .ToList();

Products and Categories have a many to many relationship. I want the categories variable to contain a list of all categories that are NOT in the retrieved product. Cannot somebody guide me in the right direction or tell me what I am doing wrong here?

Error: 'System.Nullable 1[System.Int32]' cannot be used as the data type for a sequence with an ItemExpression of type 'System.Nullable 1[System.Int32]'

As said in the comments, the direct error is in

c.ProductCategories.Select(pc => pc.Product) != product

Because c.ProductCategories.Select(pc => pc.Product) is a sequence of Product s, which can't be compared to one Product .

Another issue is that you use product in the second query. Even when used correctly, for example...

List<Category> categories = context.Categories
                .Include(c => c.ProductCategories)
                .ThenInclude(pc => pc.Product)
                .Where(c => !c.ProductCategories.Select(pc => pc.Product)
                    .Any(p => p == product))
                .ToList();

...the problem is that product can't be translated into SQL and EF switches to client-side evaluation.

(I assume you're working in EF-core. EF6 wouldn't allow it and throw an exception if you'd use product like that in a subsequent query).

But there's a simple solution that even saves you one roundtrip. Just use id directly:

List<Category> categories = context.Categories
                .Include(c => c.ProductCategories)
                .ThenInclude(pc => pc.Product)
                .Where(c => !c.ProductCategories.Any(pc => pc.ProductId == id))
                .ToList();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM