レポートのリストをテーブルに表示しようとしている多対多の関係テーブルがあります。
私のテーブルは次のようになります。
レポートテーブル:
Id| ReportName |
1 | report 1 |
2 | report 2 |
3 | report 3 |
レポートカテゴリテーブル:
Id| Name |
1 | General |
2 | Specific |
ReportMappingジャンクションテーブル:
Id| ReportId | CategoryId |
1 | 1 | 1 |
2 | 1 | 2 |
3 | 2 | 1 |
4 | 2 | 2 |
この例では、レポートに複数のカテゴリを含めることができますが、2つだけですが、1つのレポートに、General、Specific、Test2、Test3、Test4などの5つのカテゴリを含めることができます。
.netコアアプリケーションのテーブル/リストに次の行に沿ってフォーマットを表示したいと思います。
ReportId| Report Name | Report Categories
1 | report 1 | General, Specific
2 | report 2 | General, Specific
これをSQLサーバーとEFコアLINQの両方で機能させるのに問題があります。これを始める方法についての指針はありますか?これまでのところ、テーブルを結合することはできますが、複数のカテゴリを持つレポートの結果を1つの行に連結する方法がわかりません。上記の例のような希望する結果ではなく、以下のようなものが得られます。
ReportId | Report Name | Report Categories
1 | report 1 | General
1 | report 1 | Specific
2 | report 2 | General
2 | report 2 | Specific
助けていただければ幸いです、ありがとう!
説明しているモデルは、EFCoreドキュメントの多対多の例のPost
/Tag
モデルとほぼ同じです。
したがって、テーブルレコードを表す3つのクラスがあります
public class Report
{
public int Id { get; set; }
public string ReportName { get; set; }
public ICollection<ReportMapping> Mappings { get; set; } // navigation
}
public class ReportCategory
{
public int Id { get; set; }
public string Name { get; set; }
public ICollection<ReportMapping> Mappings { get; set; } // navigation
}
public class ReportMapping
{
public int Id { get; set; }
public int ReportId { get; set; }
public int CategoryId { get; set; }
public Report Report { get; set; } // navigation
public ReportCategory Category { get; set; } // navigation
}
DbSet
テーブルを表す3秒:
public DbSet<Report> Reports { get; set; }
public DbSet<ReportCategory> ReportCategories { get; set; }
public DbSet<ReportMapping> ReportMappings { get; set; }
そのノートId
接合エンティティ(テーブル)内のプロパティ(列)が冗長であるが、ので、既存のデータベースに制約されない場合には、例のようにして構成する複合PKを削除することを検討します
modelBuilder.Entity<ReportMapping>()
.HasKey(e => new { e.ReportId, e.CategoryId });
でマークされたプロパティにも注意してください// navigation
。これらはいわゆるナビゲーションプロパティ(用語の定義を参照)であり、関係の終わりを表し、join
構造を使用せずにLINQクエリ内の関連データにアクセスできます。「Linqの結合を使用しない」を参照してください。ナビゲート!LINQクエリを作成するためのEF(コア)推奨/推奨方法です。
これがデータベースモデルです。特定の結果タイプを返すクエリが必要なため、その結果を表すクラス(別名、DTO、ViewModelなど)を定義することから始めます。次に例を示します。
public class ReportInfo
{
public int ReportId { get; set; }
public string ReportName { get; set; }
public IEnumerable<string> ReportCategories { get; set; }
}
ReportCategories
単一の文字列ではなく、文字列のシーケンスとして定義していることに注意してください。これは、第1に、結果セットの文字列連結がデータベースでネイティブにサポートされていないためです。第2に、コンマとの連結は、このデータを表示できる多くの方法の1つにすぎません。一般に、データのフォーマットはクライアントの責任です。したがって、データを生のネイティブ形式(文字列のリスト)で返し、クライアントにフォーマットさせます(この場合、を使用して簡単に行うことができますstring.Join(",", info.ReportCategories)
)。
最後に、実際のクエリ。ナビゲーションプロパティを配置すると、非常に簡単になります。基本的には次Select
のとおりです。
var result = db.Reports
.Select(r => new ReportInfo
{
ReportId = r.Id,
ReportName = r.ReportName,
ReportCategories = r.Mappings
.Select(m => m.Category.Name)
.ToList() // <-- to avoid N + 1 subquery in EF Core 2.1+
})
.ToList();
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加