首页 > 解决方案 > Entity Framework core 2.1 多对多选择查询

问题描述

如何使用 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 

标签: c#entity-framework-coreasp.net-core-2.1

解决方案


在 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)

推荐阅读