web-dev-qa-db-ja.com

EF Coreで多対多の関係をクエリする方法

Webプロジェクトに.NET CoreとEF Coreを使用しています。多対多の関係を照会する方法に苦労しています。これは私のモデルがどのように見えるかです:

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

そして私のデータベースコンテキスト:

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

私がしようとしていることは、JSON結果のすべての「Begrippen」を、対応するすべての「Categories」とともに返すことですが、それらの「Categories」のリストを取得する方法がわかりません。

何か案は?前もって感謝します。

14
JessengBijleng

EF Coreは関連するプロパティを自動的にロードしないので、明示的にこれを行う必要がありますが、次のようなものがうまくいくはずです。

var result = context.Begrip
    .Include(x => x.Categories)
    .ThenInclude(x => x.category);

現時点では、インテリセンスは常に.ThenIncludeで機能するとは限りませんが、赤い下線が付いていても、コードはコンパイルする必要があります。

これをビューまたはAPIに返す場合は、.Categories[0].category.Nameなどを処理する必要がないように、DTOにマップする必要があります。

17
Richard

以下で説明する多対多の関係をフィルタリングする必要がある場合は、このようなLinQ Enumerable Anyメソッドを使用することをお勧めします。

return result.Where(x => x.Categories.Any(c => c.category == categoryId));

特定のカテゴリによって関連付けられたエンティティのフィルタリングされたリストを返す。

EntityFrameworkCore関係クエリの例

5
GAzcuy

@リチャードの答えを拡張する:

以下を実行すると、Visual Studio 2017 15.5.6で気づきました。

            return _context.Begrip
            .Include(x => x.Categories)
                .ThenInclude(y => y.<nothing typed in here yet>)

IntelliSenseは最初にy ifの場合ICollectionBegripCategoryコレクションに適したメソッドを提示し、特に「category "(「ここにはまだ何も入力されていません」の代わりに)IntelliSenseはICollectionではなく単一のインスタンスのみを扱っているかのように変更されます

ほんの少しの発言ですが、数分の時間の混乱を減らすのに役立つことを願っています。

1
GrayCat