Entity Framework 核心 2.1 多对多 Select 查询
Entity Framework core 2.1 Many To Many Select Query
如何使用 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; }
}
我已经尝试了几种不同的方法,如果我只需要一个 table 的列就可以得到结果,但无法从两个 table 中得到详细信息,即类别名称和产品名称。
编辑:
我现在添加了一个 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
//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 })));
在 EF 核心中,您需要一个联结 table 来映射 many-to-many 关系。
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)
试试这个
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();
如何使用 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; }
}
我已经尝试了几种不同的方法,如果我只需要一个 table 的列就可以得到结果,但无法从两个 table 中得到详细信息,即类别名称和产品名称。
编辑: 我现在添加了一个 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
//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 })));
在 EF 核心中,您需要一个联结 table 来映射 many-to-many 关系。
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)
试试这个
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();