Reputation: 756
How would I create the following query using Linq?
SELECT product.name, product.code, category.Name FROM product
INNER JOIN productCategories ON product.ID = productCategories.productID
INNER JOIN category ON productCategories.categoryID = category.ID
WHERE productCategories.ID = idToFind
Product & Category Classes:
public class Product
{
public Product()
{
this.Categories = new HashSet<Category>();
}
public int ID { get; set; }
public string Code { get; set; }
public string Name { get; set; }
public virtual ICollection<Category> Categories { get; set; }
}
public class Category
{
public Category()
{
this.Products = new HashSet<Product>();
this.Children = new HashSet<Category>();
}
public int ID { get; set; }
[StringLength(150)]
public string Name { get; set; }
public int? ParentID { get; set; }
public virtual Category Parent { get; set; }
public virtual ICollection<Category> Children { get; set; }
public virtual ICollection<Product> Products { get; set; }
}
I have tried a few different things and can get the results if I only need columns from one table, but can not get details from both tables i.e. category name & product name.
Edit: I have now added a JunctionClass
public class CategoryProduct
{
public int CategoryID { get; set; }
public Category Category { get; set; }
public int ProductID { get; set; }
public Product Product { get; set; }
}
and tried :
var results = _context.Product.Include(e => e.categoryProducts).ThenInclude(e => e.Category).Where(c=>c.categoryProducts.Category.ID==169).ToList();
But I still cant make it work. Getting the error:
'ICollection<CategoryProduct>' does not contain a definition for 'Category' and no accessible extension method 'Category' accepting a first argument of type 'ICollection<CategoryProduct>' could be found
Upvotes: 0
Views: 808
Reputation: 129
Try this
var idToFind = 3;
var o = (from p in _products
from c in p.Categories
where c.ID == idToFind
select new {ProductName = p.Name, ProductCode = p.Code, CategoryName = c.Name}).ToList();
Upvotes: 0
Reputation: 8947
In EF core, you need a junction table to map many-to-many relationships.
public class ProductCategory
{
public int Id { get; set; }
public int ProductId { get; set; }
public Product Product { get; set; }
public int CategoryId { get; set; }
public Category Category { get; set; }
}
public class Product
{
...
public virtual ICollection<ProductCategory> ProductCategories { get; set; }
}
public class Category
{
...
public virtual ICollection<ProductCategory> ProductCategories { get; set; }
}
// DbContext
public DbSet<ProductCategory> ProductCategories { get; set; }
public override OnModelCreating(ModelBuilder builder)
{
builder.Entity<ProductCategory>()
.HasOne(pc => pc.Product)
.WithMany(p => p.ProductCategories);
builder.Entity<ProductCategory>()
.HasOne(pc => pc.Category)
.WithMany(c => c.ProductCategories);
}
// Query
var result = await dbContext.ProductCategories
.Select(pc => new {
ProductName = pc.Product.Name,
ProductCode = pc.Product.Code,
CategoryName = pc.Category.Name
})
.SingleOrDefaultAsync(pc => pc.Id == idToFind)
Upvotes: 1
Reputation: 1
//Mock SomeData
List<Product> products = new List<Product>();
List<Category> category = new List<Category>();
//Linq
var result = products.SelectMany(product => product.Categories.SelectMany(productCategory => category.Where(category => category.ID == productCategory.ID).Select(category => new { category.Name, ProductName = product.Name, product.Code })));
Upvotes: 0