Entity Framework core 2.1 多对多选择查询
Posted
技术标签:
【中文标题】Entity Framework core 2.1 多对多选择查询【英文标题】:Entity Framework core 2.1 Many To Many Select Query 【发布时间】:2019-06-12 10:04:49 【问题描述】:如何使用 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
【问题讨论】:
缺少您查询数据的代码。到目前为止,您自己尝试过什么?并向我们展示相关的 Dbcontext 代码。 你需要明确指定一个联结表。 我现在已经添加了一个联结表,但我仍然不能让它按需要工作。 【参考方案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)
【讨论】:
谢谢,我已经添加了一个联结表,但仍然无法得到可以返回我需要的数据的东西。 有什么问题?我在这里复制了您的查询。如果您用英语陈述您的查询,我可能会查看 SQL 是否匹配。这部分对我来说是有问题的WHERE productCategories.ID = idToFind
您正在直接查找连接表,这几乎从未发生过。您是否尝试按产品 ID 进行搜索?
我没有看到滚动条。我试图做 dbContext.Product,然后获取 categoryproducts,然后是类别。但是我不断收到语法错误。您的查询效果很好。
重要的是,在 EF Core 5.0 中你不再需要连接表:docs.microsoft.com/en-us/ef/core/what-is-new/ef-core-5.0/…【参考方案2】:
//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 )));
【讨论】:
当我尝试时:var result = _context.Product.SelectMany(product => product.categoryProducts.SelectMany(productCategory => _context.Category.Where(category => category.ID == 169)。 Select(category => new category.Name, ProductName = product.Description, product.Code )));我得到一个错误:必须是可约节点 请在您的答案中添加解释。【参考方案3】:试试这个
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();
【讨论】:
以上是关于Entity Framework core 2.1 多对多选择查询的主要内容,如果未能解决你的问题,请参考以下文章
Entity Framework core 2.1 多对多选择查询
使用 Entity Framework Core (2.1) 调用标量函数的最佳实践
Entity Framework Core 2.1 无法更新具有关系的实体