如何在EF Core中查询多对多关系

Jes*_*vdb 10 c# asp.net-mvc entity-framework entity-framework-core asp.net-core

我正在使用.NET Core和EF Core进行Web项目.我正在努力如何查询多对多的关系.这就是我的模型:

public class Begrip
{
    public int ID { get; set; }
    public string Name { get; set; } 
    public string Desc { get; set; }
    [Url]
    public string URL { get; set; } 
    public ICollection<BegripCategory> Categories { get; set; } 
}

public class Category
{
    public int ID { get; set; }
    public string Name { get; set; } 
    public ICollection<BegripCategory> Begrippen { get; set; }
}

public class BegripCategory
{
    public int begripId { get; set; }
    public Begrip begrip { get; set; } 
    public int categoryId { get; set; }
    public Category category { get; set; } 
}
Run Code Online (Sandbox Code Playgroud)

我的数据库上下文:

public class PBBContext : DbContext
{
    public PBBContext (DbContextOptions<PBBContext> options)
        : base(options)
    {
    }

    public DbSet<PBB.Models.Movie> Movie { get; set; }
    public DbSet<PBB.Models.Begrip> Begrip { get; set; } 
    public DbSet<PBB.Models.Category> Category { get; set; } 
    public DbSet<PBB.Models.BegripCategory> BegripCategory { get; set; }

    protected override void OnModelCreating(ModelBuilder modelbuilder)
    {
        modelbuilder.Entity<BegripCategory>().HasKey(bc => new { bc.begripId, bc.categoryId });

        modelbuilder.Entity<BegripCategory>().HasOne(b => b.begrip).WithMany(bg => bg.Categories).HasForeignKey(bc => bc.begripId);
        modelbuilder.Entity<BegripCategory>().HasOne(c => c.category).WithMany(ca => ca.Begrippen).HasForeignKey(cc => cc.categoryId);
    }
}
Run Code Online (Sandbox Code Playgroud)

我试图做的是返回所有相应"类别"的JSON结果中的所有"Begrippen",但是,我无法弄清楚如何获取它们的"类别"列表.

有任何想法吗?提前致谢.

Ric*_*ard 17

EF Core不会自动加载相关属性,因此您需要明确地执行此操作,但以下内容应该可以解决这个问题:

var result = context.Begrip
    .Include(x => x.Categories)
    .ThenInclude(x => x.category);
Run Code Online (Sandbox Code Playgroud)

注意,智能感知目前并不总是有效.ThenInclude,但代码仍应编译,即使它有红色下划线.

如果您将其返回到视图或API,您可能希望将其映射到DTO,这样您就不必处理.Categories[0].category.Name等等.


Gra*_*Cat 6

扩展@Richard的答案:

当我执行以下操作时,我在 Visual Studio 2017 15.5.6 中注意到:

            return _context.Begrip
            .Include(x => x.Categories)
                .ThenInclude(y => y.<nothing typed in here yet>)
Run Code Online (Sandbox Code Playgroud)

IntelliSense 首先告诉我,如果BegripCategory的ICollection类型呈现适合集合的方法,那么令人困惑的是,特别是当我开始输入“类别”(代替“此处尚未输入任何内容”)时,IntelliSense 会发生变化,就好像我们正在处理一样只有一个实例而不是ICollection

只是一个小小的评论,但我希望它能帮助节省几分钟的时间混乱。


小智 6

如果需要过滤下面描述的多对多关系,建议使用LinQ Enumerable Any方法,例如:

return result.Where(x => x.Categories.Any(c => c.category == categoryId));
Run Code Online (Sandbox Code Playgroud)

返回与特定类别相关的实体的过滤列表。

EntityFrameworkCore关系查询示例