Entity Framework core 2.1 «Многие ко многим» выбирают запрос - PullRequest
0 голосов
/ 12 июня 2019

Как мне создать следующий запрос с помощью 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

Классы продуктов и категорий:

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; }
}

Я пробовал несколько разных вещей и могу получить результаты, если янужны только столбцы из одной таблицы, но не может получить подробности из обеих таблиц, т. е. название категории и название продукта.

Редактировать: я добавил класс JunctionClass

public class CategoryProduct
{
    public int CategoryID { get; set; }
    public Category Category { get; set; }

    public int ProductID { get; set; }
    public Product Product { get; set; }

}

и попытался:

var results = _context.Product.Include(e => e.categoryProducts).ThenInclude(e => e.Category).Where(c=>c.categoryProducts.Category.ID==169).ToList();

Но я все еще не могу заставить его работать.Получение ошибки:

'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 

Ответы [ 3 ]

1 голос
/ 12 июня 2019

В ядре EF требуется таблица соединений для сопоставления отношений «многие ко многим».

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)
0 голосов
/ 12 июня 2019

Попробуйте это

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();
0 голосов
/ 12 июня 2019
//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 })));
...