質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
LINQ

LINQとはLanguage INtegrated Queryの略で、「統合言語クエリ」という意味です。C#やVisual Basicといった言語のコード内に記述することができるクエリです。

Q&A

解決済

1回答

2656閲覧

LINQ 左外部結合のやり方について

abd1106

総合スコア12

LINQ

LINQとはLanguage INtegrated Queryの略で、「統合言語クエリ」という意味です。C#やVisual Basicといった言語のコード内に記述することができるクエリです。

0グッド

0クリップ

投稿2021/10/24 13:45

編集2021/10/24 14:22

LINQで外部結合のやり方を調べるために試行錯誤しましたが、分かりませんでした。

以下の例は、TraderテーブルとItemsテーブルのID列で結合して、Id列の値1~6を出力するようにしたいです。

何か良い方法はありませんでしょうか。
また、インターネットで調べた際に、外部結合の例でGroupJoinとSelectManyが使われておりましたが、外部結合はできないのでしょうか。

環境は、.NetCore 3.1 でVisual Studioを使用しております。
※本当はコントローラに書くのは良くないということは分かっていますが、動作確認が容易だと判断してあえてここに記載しています。

LINQ

1using Microsoft.AspNetCore.Mvc; 2using QuickMaster.Models; 3using QuickMaster.Views; 4using System; 5using System.Collections.Generic; 6using System.Linq; 7using System.Web; 8using WebApplication1.Models; 9using System.IO; 10 11namespace WebApplication1.Controllers 12{ 13 public class HomeController : Controller 14 { 15 private readonly MyContext _context; 16 17 public HomeController(MyContext context) 18 { 19 this._context = context; 20 } 21 22 public ActionResult Index() 23 { 24 25 Trader[] traders = new Trader[] { 26 new Trader() { Id = 1, CompanyNm = "株式会社ABC", Address = "北海道" }, 27 new Trader() { Id = 2, CompanyNm = "株式会社DEF", Address = "青森" }, 28 new Trader() { Id = 3, CompanyNm = "株式会社GHI", Address = "秋田" }, 29 new Trader() { Id = 4, CompanyNm = "株式会社HIJ", Address = "岩手" }, 30 new Trader() { Id = 5, CompanyNm = "株式会社KLM", Address = "山形" }, 31 new Trader() { Id = 6, CompanyNm = "株式会社OPQ", Address = "宮城" }, 32 }; 33 34 ItemList[] items = new ItemList[] { 35 new ItemList() { Id = 1, Price = 100, ExpiryDate = new DateTime(2000, 4, 1) }, 36 new ItemList() { Id = 2, Price = 200, ExpiryDate = new DateTime(2005, 5, 1) }, 37 new ItemList() { Id = 3, Price = 300, ExpiryDate = new DateTime(2010, 6, 1) }, 38 new ItemList() { Id = 4, Price = 400, ExpiryDate = new DateTime(2015, 7, 1) }, 39 new ItemList() { Id = 5, Price = 2020, ExpiryDate = new DateTime(2020, 8, 1) } 40 }; 41 42 43 var result = traders.GroupJoin( 44 items, 45 trader => trader.Id, 46 item => item.Id, 47 (trader, item) => new { trader, item }) 48 .SelectMany(o => o.item, (j, k) => new 49 { 50 Id = j.trader.Id, 51 CompanyNm = j.trader.CompanyNm, 52 Address = j.trader.Address, 53 Price = k.Price, 54 ExpireDate = k.ExpiryDate 55 }); 56 57 foreach (var o in result) 58 { 59 Console.WriteLine($"Id={o.Id}, CompanyNm={o.CompanyNm}, Address={o.Address}, Price={o.Price}, ExpireDate={o.ExpireDate}"); 60 } 61 return View(); 62 } 63 } 64}

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

DefaultIfEmptyを使うと、外部結合に相当する挙動にできます。

c#

1class Program { 2 static void Main(string[] args) { 3 Trader[] traders = new Trader[] { 4 new Trader() { Id = 1, CompanyNm = "株式会社ABC", Address = "北海道" }, 5 new Trader() { Id = 2, CompanyNm = "株式会社DEF", Address = "青森" }, 6 new Trader() { Id = 3, CompanyNm = "株式会社GHI", Address = "秋田" }, 7 new Trader() { Id = 4, CompanyNm = "株式会社HIJ", Address = "岩手" }, 8 new Trader() { Id = 5, CompanyNm = "株式会社KLM", Address = "山形" }, 9 new Trader() { Id = 6, CompanyNm = "株式会社OPQ", Address = "宮城" }, 10 }; 11 12 ItemList[] items = new ItemList[] { 13 new ItemList() { Id = 1, Price = 100, ExpiryDate = new DateTime(2000, 4, 1) }, 14 new ItemList() { Id = 2, Price = 200, ExpiryDate = new DateTime(2005, 5, 1) }, 15 new ItemList() { Id = 3, Price = 300, ExpiryDate = new DateTime(2010, 6, 1) }, 16 new ItemList() { Id = 4, Price = 400, ExpiryDate = new DateTime(2015, 7, 1) }, 17 new ItemList() { Id = 5, Price = 2020, ExpiryDate = new DateTime(2020, 8, 1) } 18 }; 19 20 21 var result = traders.GroupJoin( 22 items, 23 trader => trader.Id, 24 item => item.Id, 25 (trader, item) => new { trader, item }) 26 .SelectMany( 27 o => o.item.DefaultIfEmpty(), // traderに結合されるitemがない場合は、itemをnullにする 28 (j, k) => new { 29 Id = j.trader.Id, 30 CompanyNm = j.trader.CompanyNm, 31 Address = j.trader.Address, 32 Price = k?.Price, // itemがnullの場合はPrice/ExpiryDateは参照しない 33 ExpireDate = k?.ExpiryDate 34 } 35 ); 36 37 foreach (var o in result) { 38 Console.WriteLine($"Id={o.Id}, CompanyNm={o.CompanyNm}, Address={o.Address}, Price={o.Price}, ExpireDate={o.ExpireDate}"); 39 } 40 } 41 42 class Trader { 43 public int Id { get; set; } 44 public string CompanyNm { get; set; } 45 public string Address { get; set; } 46 } 47 48 class ItemList { 49 public int Id { get; set; } 50 public int Price { get; set; } 51 public DateTime ExpiryDate { get; set; } 52 } 53}

出力。

Id=1, CompanyNm=株式会社ABC, Address=北海道, Price=100, ExpireDate=00/04/01 0:00:00 Id=2, CompanyNm=株式会社DEF, Address=青森, Price=200, ExpireDate=05/05/01 0:00:00 Id=3, CompanyNm=株式会社GHI, Address=秋田, Price=300, ExpireDate=10/06/01 0:00:00 Id=4, CompanyNm=株式会社HIJ, Address=岩手, Price=400, ExpireDate=15/07/01 0:00:00 Id=5, CompanyNm=株式会社KLM, Address=山形, Price=2020, ExpireDate=20/08/01 0:00:00 Id=6, CompanyNm=株式会社OPQ, Address=宮城, Price=, ExpireDate=

投稿2021/10/24 14:34

編集2022/08/16 13:34
jhashimoto

総合スコア838

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

abd1106

2021/10/24 14:52

ご回答いただき、ありがとうございます。 大変分かりやすかったです。 こちらの環境でも実現できました。 本当にありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問