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

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

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

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

Q&A

解決済

2回答

1665閲覧

C# LINQでJOINをした結果をWHERE句で抽出レコードを限定する方法

abd1106

総合スコア12

LINQ

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

0グッド

0クリップ

投稿2021/10/21 12:12

LINQのメソッド構文で、分からないことがあり、教えていただければと考えております。

2つのテーブルをJOINした後に、WHERE句で抽出レコードを限定したいのですが、いろいろ試したり、調べた結果、分かりませんでした。

以下のように、JOINまでは何とかできたと考えておりますが、WHERE句(今回の例の場合、ExpiryDateより後かどうか)でどうしてもコンパイルエラーになってしまいます。

何か良い方法はありますでしょうか。
(例の画像にある、Traderテーブルに対して、ItemListテーブルをJoinする前提でお願いします)

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

C#

1using Microsoft.AspNetCore.Mvc; 2using QuickMaster.Models; 3using System.Collections.Generic;using System.Linq; 4 5namespace WebApplication1.Controllers 6{ 7 public class HomeController : Controller 8 { 9 private readonly MyContext _context; 10 11 public HomeController(MyContext context) 12 { 13 this._context = context; 14 } 15 16 public ActionResult Index() 17 { 18 19 var query1 = (from m in _context.Trader select m).ToList(); 20 var query2 = (from n in _context.ItemList select n).ToList(); 21 22 var result = query1.GroupJoin( 23 query2, 24 x => x.id, 25 y => y.id, 26 (s, t) => 27 new { t }).ToList(); 28 return View(); 29 } 30 } 31}

・テーブルの一覧と実現したいこと
実現したいことの画像

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

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

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

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

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

guest

回答2

0

SelectManyの代わりにクエリ構文でfromを使うと、シンプルに書けます。

c#

1var query = 2 from trader in traders 3 from item in items 4 where 5 trader.Id == item.Id && 6 item.ExpiryDate > new DateTime(2010, 1, 1) 7 select new { 8 Id = trader.Id, 9 CompanyNm = trader.CompanyNm, 10 Address = trader.Address, 11 Price = item.Price, 12 ExpireDate = item.ExpiryDate 13 }; 14 15var result = query.ToList();

From … From … (SelectMany) - クエリ式の構文例:射影 - ADO.NET | Microsoft Docs

投稿2021/10/21 23:36

編集2022/08/16 13:36
jhashimoto

総合スコア838

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

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

abd1106

2021/10/22 03:05

クエリ構文の方が個人的には好きなのですが、メソッド構文の方がよく使われる?というのをインターネットで見たので、メソッド構文で学習をしておりました。クエリ構文の方がスッキリしていて、私はこちらの方が好きです・・。別の実現方法の提示、ありがとうございました。
jhashimoto

2021/10/22 13:45

メソッド構文はLINQのすべての機能を使えますが、クエリ構文では一部の機能が使えません。 https://docs.microsoft.com/ja-jp/dotnet/csharp/programming-guide/concepts/linq/query-syntax-and-method-syntax-in-linq > 一部のクエリは、メソッド呼び出しとして表現する必要があります。 たとえば、指定した条件に一致する要素の数を取得するクエリを表すには、メソッド呼び出しを使用する必要があります。 また、ソース シーケンスで最大の値を持つ要素を取得するクエリにも、メソッド呼び出しを使用する必要があります。 一方で、クエリ構文の方がシンプルに表現できるケースがあり、一長一短だと思います。私は普段メソッド構文で書いてますが、シンプルに書けるときはクエリ構文を選択します。ご参考まで。
guest

0

ベストアンサー

こんな感じでどうでしょうか。

c#

1using System; 2using System.Linq; 3 4namespace LinqSample { 5 class Program { 6 static void Main(string[] args) { 7 var traders = new Trader[] { 8 new Trader() { Id = 1, CompanyNm = "株式会社ABC", Address = "北海道" }, 9 new Trader() { Id = 2, CompanyNm = "株式会社DEF", Address = "青森" }, 10 new Trader() { Id = 3, CompanyNm = "株式会社GHI", Address = "秋田" }, 11 new Trader() { Id = 4, CompanyNm = "株式会社HIJ", Address = "岩手" }, 12 new Trader() { Id = 5, CompanyNm = "株式会社KLM", Address = "山形" }, 13 new Trader() { Id = 6, CompanyNm = "株式会社OPQ", Address = "宮城" }, 14 }; 15 16 var items = new ItemList[] { 17 new ItemList() { Id = 1, Price = 100, ExpiryDate = new DateTime(2000, 4, 1) }, 18 new ItemList() { Id = 2, Price = 200, ExpiryDate = new DateTime(2005, 5, 1) }, 19 new ItemList() { Id = 3, Price = 300, ExpiryDate = new DateTime(2010, 6, 1) }, 20 new ItemList() { Id = 4, Price = 400, ExpiryDate = new DateTime(2015, 7, 1) }, 21 new ItemList() { Id = 5, Price = 2020, ExpiryDate = new DateTime(2020, 8, 1) } 22 }; 23 24 var result = traders.GroupJoin( 25 items, 26 trader => trader.Id, 27 item => item.Id, 28 (trader, item) => new { trader, item }) 29 // シーケンスの展開 30 .SelectMany(traderAndItem => traderAndItem.item, (trader, item) => new { 31 Id = trader.trader.Id, 32 CompanyNm = trader.trader.CompanyNm, 33 Address = trader.trader.Address, 34 Price = item.Price, 35 ExpireDate = item.ExpiryDate 36 }) 37 .Where(o => o.ExpireDate > new DateTime(2010, 1, 1)) 38 .ToList(); 39 40 foreach (var o in result) { 41 Console.WriteLine($"Id={o.Id}, CompanyNm={o.CompanyNm}, Address={o.Address}, Price={o.Price}, ExpireDate={o.ExpireDate}"); 42 } 43 } 44 } 45 46 class Trader { 47 public int Id { get; set; } 48 public string CompanyNm { get; set; } 49 public string Address { get; set; } 50 } 51 52 class ItemList { 53 public int Id { get; set; } 54 public int Price { get; set; } 55 public DateTime ExpiryDate { get; set; } 56 } 57} 58 59

出力。

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

投稿2021/10/21 23:30

編集2022/08/16 13:37
jhashimoto

総合スコア838

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

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

abd1106

2021/10/22 03:02

ご回答いただき、ありがとうございます。 やりたいことが無事実現できました! ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問