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.