Entity Framework Core でテーブルのLEFT JOIN (テーブル結合)をするコードを紹介します。
概要
こちらの記事ではJOIN(INNER JOIN)のコードを紹介しました。
この記事では、Entity Framework Core でテーブルをLEFT JOINして対応する値を取得するコードを紹介します。
LEFT JOINを実行する場合は、GroupJoin メソッドを利用し、SelectManyメソッド内で、DefaultIfEmpty() メソッドを呼び出します。
書式
メソッド構文
LEFT JOINですべてのフィールドを取得する場合の書式は以下になります。
結果は匿名型(Anonymous型)で戻るため、
IQueryable<dynamic>
型の変数に代入します。
(結合元テーブルのDbSet)
.GroupJoin(
(結合先テーブルのDbSet), (結合元テーブルの一時名) => (結合元テーブルの一時名).(JOIN対象のフィールド),
(結合先テーブルの一時名)=> (結合先テーブルの一時名).(JOIN対象のフィールド),
( (結合元テーブルの返却オブジェクトのフィールド名), (結合先テーブルの返却オブジェクトのフィールド名) )
=> new { (結合元テーブルの返却オブジェクトのフィールド名), (結合先テーブルの返却オブジェクトのフィールド名) })
.SelectMany(
(レコードの一時名) => (レコードの一時名).(GroupJoin先のテーブルのオブジェクト).DefaultIfEmpty(),
( (レコードの一時名), (Join先レコードの一時名) )
=> new { レコードの一時名).(Join元のテーブルオブジェクト), (Join先レコードの一時名) });
プログラム例
テーブルの準備
データベースに以下のテーブルを用意します。
ProductsD テーブルのstockplace フィールドと ProductsDStockPlace テーブルの id フィールドを結合した結果を取得します。
ProductsD テーブル id | name | stockplace | category | price |
1 | ぺんぎんクッキー | 1 | 1 | 180 |
2 | らくだキャラメル | 3 | 2 | 95 |
3 | しろくまアイス | 2 | 3 | 230 |
4 | かるがもサブレ | 1 | 1 | 160 |
5 | あるぱかカステラ | 2 | 2 | 420 |
6 | あひるタルト | 4 | 1 | 260 |
ProductsDStockPlace テーブル id | name |
1 | 東京 |
2 | 札幌 |
3 | 福岡 |
UI
下図のフォームを作成します。ボタンとMultilinesプロパティを
True
に設定したテキストボックスを配置します。
コード
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using EntityFrameworkCoreJoin.Models;
namespace EntityFrameworkCoreJoin
{
public partial class FormLeftJoin : Form
{
public FormLeftJoin()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
IQueryable<dynamic> rec;
IPentecSandBoxContext sc = new IPentecSandBoxContext();
rec = sc.ProductsDs.GroupJoin(sc.ProductsDstockPlaces, pd_table => pd_table.Stockplace, pdsp_table => pdsp_table.Id, (pd_table, pdsp_table) => new { pd_table, pdsp_table })
.SelectMany(rec => rec.pdsp_table.DefaultIfEmpty(), (rec, pdsp_table2) => new { rec.pd_table, pdsp_table2 });
foreach (var r in rec) {
textBox1.Text += string.Format("{0} \\{1:d} : {2}\r\n", r.pd_table.Name.Trim(), r.pd_table.Price, r.pdsp_table2?.Name.Trim());
}
}
}
}
解説
LEFT JOINを実行するLINQが以下のコードです。
rec = sc.ProductsDs
.GroupJoin(sc.ProductsDstockPlaces, pd_table => pd_table.Stockplace, pdsp_table => pdsp_table.Id, (pd_table, pdsp_table) => new { pd_table, pdsp_table })
.SelectMany(rec => rec.pdsp_table.DefaultIfEmpty(), (rec, pdsp_table2) => new { rec.pd_table, pdsp_table2 });
GroupJoinを実行します。JOIN元のテーブル
ProductsD
のStockplaceフィールドとJOIN先のテーブル
ProductsDStockPlace
のIdフィールドで結合します。
GroupJoinの動作の詳細は
こちらの記事を参照してください。
.GroupJoin(sc.ProductsDstockPlaces, pd_table => pd_table.Stockplace, pdsp_table => pdsp_table.Id, (pd_table, pdsp_table) => new { pd_table, pdsp_table })
SelectManyメソッドで、GroupJoinの結果から、
DefaultIfEmpty()
メソッドを呼び出します。
.SelectMany(rec => rec.pdsp_table.DefaultIfEmpty(), (rec, pdsp_table2) => new { rec.pd_table, pdsp_table2 });
実行結果
プロジェクトを実行します。下図のウィンドウが表示されます。
[button1]をクリックします。下図の結果が表示されます。
Join先が無いid=6 の"あひるタルト"のレコードも結果に表示される動作が確認できます。
実行されるSQL文を確認します。LEFT JOINのSQL文が実行されています。
SELECT [p].[id], [p].[category], [p].[name], [p].[price], [p].[stockplace], [p0].[id], [p0].[name]
FROM [ProductsD] AS [p]
LEFT JOIN [ProductsDStockPlace] AS [p0] ON [p].[stockplace] = [p0].[id]
著者
iPentecのメインプログラマー
C#, ASP.NET の開発がメイン、少し前まではDelphiを愛用
最終更新日: 2023-07-08
作成日: 2023-07-08