实体框架核心2.1多对多选择查询

时间:2019-06-12 10:04:49

标签: c# entity-framework-core asp.net-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 

3 个答案:

答案 0 :(得分: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)

答案 1 :(得分:0)

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

答案 2 :(得分:0)

尝试一下

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();