You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在EF Core中实现多对多关联查询并按Active字段筛选记录

EF Core 实现关联查询方案

你可以通过两种方式实现该需求,分别适配是否配置了实体导航属性的场景:


前提准备

首先确保你的DbContext中已经注册了所有对应表的DbSet:

// 你的DbContext类中添加以下属性
public DbSet<ProductCategory> ProductCategories { get; set; }
public DbSet<Product> Products { get; set; }
public DbSet<ProductComplementCategory> ProductComplementCategories { get; set; }
public DbSet<ComplementCategory> ComplementCategories { get; set; }
public DbSet<ComplementCategoryComplement> ComplementCategoryComplements { get; set; }
public DbSet<Complement> Complements { get; set; }

方案1:手动Join(和原生SQL逻辑完全对齐,无需依赖导航属性)

这种写法和你给出的SQL逻辑一一对应,不需要提前配置实体间的导航关系,适配度最高:

var queryResult = await _dbContext.ProductCategories
    // 关联Product表
    .Join(_dbContext.Products,
        pc => pc.Uid,
        p => p.ProductCategoryId,
        (pc, p) => new { pc, p })
    // 关联ProductComplementCategory表
    .Join(_dbContext.ProductComplementCategories,
        join1 => join1.p.Uid,
        pcc => pcc.ProductID,
        (join1, pcc) => new { join1.pc, join1.p, pcc })
    // 关联ComplementCategory表
    .Join(_dbContext.ComplementCategories,
        join2 => join2.pcc.ComplementCategoryID,
        cc => cc.Uid,
        (join2, cc) => new { join2.pc, join2.p, cc })
    // 关联ComplementCategoryComplements表
    .Join(_dbContext.ComplementCategoryComplements,
        join3 => join3.cc.Uid,
        ccc => ccc.ComplementCategoryID,
        (join3, ccc) => new { join3.pc, join3.p, join3.cc, ccc })
    // 关联Complement表
    .Join(_dbContext.Complements,
        join4 => join4.ccc.ComplementID,
        c => c.Uid,
        (join4, c) => new { join4.pc, join4.p, join4.cc, c })
    // 筛选四个表Active=1的条件
    .Where(result => result.pc.Active == 1 
                    && result.p.Active == 1 
                    && result.cc.Active == 1 
                    && result.c.Active == 1)
    // 最终返回所需字段,和SQL逻辑一致返回四个表的全部字段
    .Select(result => new 
    {
        ProductCategory = result.pc,
        Product = result.p,
        ComplementCategory = result.cc,
        Complement = result.c
    })
    .ToListAsync();

如果你的Active字段是布尔类型,把筛选条件里的==1改为==true即可。


方案2:导航属性查询(EF Core推荐写法,需提前配置关联关系)

如果你的实体已经配置了对应导航属性(比如Product实体中有ProductCategory导航属性、Product实体中有ProductComplementCategories集合导航属性等),可以用更简洁的写法:

var queryResult = await _dbContext.ProductCategories
    .Include(pc => pc.Products)
        .ThenInclude(p => p.ProductComplementCategories)
            .ThenInclude(pcc => pcc.ComplementCategory)
                .ThenInclude(cc => cc.ComplementCategoryComplements)
                    .ThenInclude(ccc => ccc.Complement)
    .Where(pc => pc.Active == 1
                && pc.Products.Any(p => p.Active == 1)
                && pc.Products.SelectMany(p => p.ProductComplementCategories)
                    .Select(pcc => pcc.ComplementCategory)
                    .Any(cc => cc.Active == 1)
                && pc.Products.SelectMany(p => p.ProductComplementCategories)
                    .SelectMany(pcc => pcc.ComplementCategory.ComplementCategoryComplements)
                    .Select(ccc => ccc.Complement)
                    .Any(c => c.Active == 1))
    .Select(pc => new 
    {
        ProductCategory = pc,
        Products = pc.Products.Where(p => p.Active == 1),
        ComplementCategories = pc.Products
            .SelectMany(p => p.ProductComplementCategories)
            .Select(pcc => pcc.ComplementCategory)
            .Where(cc => cc.Active ==1),
        Complements = pc.Products
            .SelectMany(p => p.ProductComplementCategories)
            .SelectMany(pcc => pcc.ComplementCategory.ComplementCategoryComplements)
            .Select(ccc => ccc.Complement)
            .Where(c => c.Active ==1)
    })
    .ToListAsync();

两种写法最终生成的SQL和你给出的原生SQL逻辑一致,可根据实际项目配置选择使用。

内容的提问来源于stack exchange,提问作者Lucas Finetti

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 17:27:04