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

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

新規登録して質問してみよう
ただいま回答率
85.50%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

MVC

MVC(Model View Controller)は、オブジェクト指向プログラミングにおけるモデル・ビュー・コントローラーの総称であり、ソフトフェア開発で使われている構築パターンとしても呼ばれます。

.NET Framework

.NET Framework は、Microsoft Windowsのオペレーティングシステムのために開発されたソフトウェア開発環境/実行環境です。多くのプログラミング言語をサポートしています。

LINQ

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

ASP.NET

ASP.NETは動的なWebサイトやWebアプリケーション、そしてWebサービスを構築出来るようにする為、Microsoftによって開発されたウェブアプリケーション開発フレームワークです。

Q&A

解決済

4回答

2152閲覧

LINQのクエリ式で文字列を集計したい

okanegahosii

総合スコア14

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

MVC

MVC(Model View Controller)は、オブジェクト指向プログラミングにおけるモデル・ビュー・コントローラーの総称であり、ソフトフェア開発で使われている構築パターンとしても呼ばれます。

.NET Framework

.NET Framework は、Microsoft Windowsのオペレーティングシステムのために開発されたソフトウェア開発環境/実行環境です。多くのプログラミング言語をサポートしています。

LINQ

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

ASP.NET

ASP.NETは動的なWebサイトやWebアプリケーション、そしてWebサービスを構築出来るようにする為、Microsoftによって開発されたウェブアプリケーション開発フレームワークです。

0グッド

0クリップ

投稿2021/02/05 15:50

編集2021/02/06 00:41

C#のLINQに関する質問です。
DBのデータの集計で、文字列の集計方法がわかりません。
クエリ式での集計方法を模索中で、teratailユーザーさんにご助力願いたいと思います。

自分で調べて目指す処理をSQLで実現する例を見つけたものの、LINQ初心者でLINQにうまく落とし込めない状態です。

作成中の画面:2画面

- 横2列の一覧画面(以下:【地方一覧画面】)
・左列:日本の地方名(東北、四国など)
・右列:URLつきの「詳細」

- 横3列の各地方の詳細情報画面(以下:【詳細画面】)
・左列:その地方の都道府県名
・中列:その地方の県庁所在地
・右列:その地方の名産品

現状の問題点、実現イメージ、前提条件

イメージ説明
- 現状の問題点
・DBでは名産品を1行1つしか取得できないため、同じ自治体の情報が何列にもなってしまう

- 修正イメージ
・DBに同じ都道府県の詳細情報が格納されている場合、読点「、」で区切る
・同じ都道府県を一列でまとめたい(上図の右下「完成イメージ」参照)
可能な限りメソッド式を使わず、クエリ式で記述したい

- 前提条件
・(当たり前ですが)都道府県と県庁所在地は一意
・詳細画面のあと、「戻る」ボタンで地方一覧画面に戻ります
今回の質問は、データベースから取得した文字列の集計です

開発環境

・windows10(2016)
・IIS ver10.0
・Visual Studio 2019
・SQL Server 2016
・.NET Framework ver4.5
・ASP.NET MVC ver5.2.7
・Chrome(最新)
・言語:C#

コード

今回の投稿に必要そうな箇所のみ抜き出しています。
現状でエラーなく画面操作はできている状態です。

ファイル名:ChubuViewModel.cs

C#

1namespace Chubu.ViewModel 2{ 3  public class ChubuViewModel 4  { 5    // メインは詳細画面のため、地方一覧画面に関する記述は省略 6 7    public List<ChubuInfoRow> Items {get; set;} 8 9    public class ChubuInfoRow 10    { 11      [DisplayName"都道府県"] 12      public string TdfkName {get; set;} 13 14      [DisplayName"県庁所在地"] 15      public string KenchoName {get; set;} 16 17      [DisplayName"県の名産品"] 18      public string MeisanName {get; set;} 19    } 20  } 21}

ファイル名:ChubuModel.cs
(ViewModelはUsing済)

C#

1namespace Chubu.Models 2{ 3  public class ChubuModel 4  { 5    public ChubuViewModel = GetChubuViewModel(string tdfkId) 6    { 7      ChubuViewModel model = new ChubuViewModel(); 8 9      using (DataBase db = new Database()) 10      { 11        var tdfkNo = "004"; // 中部地方。「地方一覧画面」の北海道が"001"のイメージ。 12        // 「地方一覧画面」から地方ごとのコードを取得するコードが未実装のため、中部地方を仮置きしています。 13 14        // 「地方一覧画面」左列(日本の地方名)を取得 15        var x = from a in db.Areas 16         where a.tdfk_cd = tdfkNo 17         select new ChubuViewModel 18         { 19           AreaName = a.area_nm  20         }; 21 22        // 「詳細画面」のテーブルを取得 23        var y = from a in db.Areas 24         where a.tdfk_cd = tdfkNo 25         join b in db.TdfkInfos on a.tdfk_cd equals b.tdfk_cd 26         join c in db.TdfkDetailInfos 27         on new {a.tdfk_cd, b.register_no} equals new {c.tdfk_cd, c.register_no} 28         join d in db.Meisanhins on a.meisan_nm equals meisan_nm 29 30         select new ChubuViewModel.ChubuInfoRow 31         { 32           TdfkName = b.tdfk_nm, 33           KenchoName = b.kencho_nm, 34           MeisanName = d.meisan_nm, 35         }; 36 37        // このあとItemsにyを入れる記述がありますが、ここでは省略。 38 39      } 40    } 41  } 42}

DBのイメージ

イメージ説明
・Areas:日本の地方の情報を格納
・TdfkInfos:都道府県の情報を格納
・TdfkDetailInfos:都道府県の詳細情報(県庁の住所など)を格納
・Meisanhins:都道府県の名産品情報を格納

以上です。
長い説明かつ抽象的な記述のみで申し訳ありませんが、ご回答いただければと思います。
よろしくお願いします。

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

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

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

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

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

退会済みユーザー

退会済みユーザー

2021/02/05 22:31

画像の「現状」はコードの変数 y に取得できているので、それを Linq で加工して画像の「完成イメージ」のオブジェクトを作るということでいいのですか?
okanegahosii

2021/02/06 00:24

仰る通りです! 「現状」から「完成イメージ」に加工する手段を知りたく投稿しました。
guest

回答4

0

ベストアンサー

・DBに同じ都道府県の詳細情報が格納されている場合、読点「、」で区切る

・同じ都道府県を一列でまとめたい(上図の右下「完成イメージ」参照)
・可能な限りメソッド式を使わず、クエリ式で記述したい

クエリ結果のグループ化 を試してください。

クエリ構文は書いたことがないので、試しにメソッド構文で書いてみました。
メソッド構文で書けることはクエリ構文でも書けるので、上記URLと下記ソースコードを参考にクエリ構文でのコードは自助努力で製作してください。

C#

1var groups = y.GroupBy(x => new{ x.TdfkName, x.KenchoName}); 2foreach(var group in groups){ 3 Console.WriteLine("key:{0}", group.Key); 4 Console.WriteLine("名産品一覧:{0}", string.Join("、", group.Select(x => x.MeisanName)); 5}

投稿2021/02/06 00:04

編集2021/02/06 00:09
BluOxy

総合スコア2663

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

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

okanegahosii

2021/02/06 00:25

ありがとうございます! 自分の勉強にもなるので、クエリ構文化は自力で頑張ります。
guest

0

要するにコレクション内にある要素を一つの要素にまとめたいという事でしょう。
Aggregateを使えば実現できそうなんで、以下の簡単な例を参考に考えてみれば良いんでは。

Concat all strings inside a List<string> using LINQ

投稿2021/02/05 15:58

gentaro

総合スコア8949

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

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

okanegahosii

2021/02/06 00:33

ありがとうございます! Aggregateですね、添付いただいたものを読んで自分で考えてみます。
guest

0

質問で掲載したコードに追記する形で記載します。

ファイル名:ChubuModel.cs
(ViewModelはUsing済)

C#

1namespace Chubu.Models 2{ 3  public class ChubuModel 4  { 5    public ChubuViewModel = GetChubuViewModel(string tdfkId) 6    { 7      ChubuViewModel model = new ChubuViewModel(); 8 9      using (DataBase db = new Database()) 10      { 11        var tdfkNo = "004"; // 中部地方。 12 13        // 「地方一覧画面」左列(日本の地方名)を取得 14        var x = from a in db.Areas 15         where a.tdfk_cd = tdfkNo 16         select new ChubuViewModel 17         { 18           AreaName = a.area_nm  19         }; 20 21        // 「詳細画面」のテーブルを取得 22        var y = from a in db.Areas 23         where a.tdfk_cd = tdfkNo 24         join b in db.TdfkInfos on a.tdfk_cd equals b.tdfk_cd 25         join c in db.TdfkDetailInfos 26         on new {a.tdfk_cd, b.register_no} equals new {c.tdfk_cd, c.register_no} 27         join d in db.Meisanhins on a.meisan_nm equals meisan_nm 28 29         select new ChubuViewModel.ChubuInfoRow 30         { 31           TdfkName = b.tdfk_nm, 32           KenchoName = b.kencho_nm, 33           MeisanName = d.meisan_nm, 34         }; 35 36        // ここから自己解決の処理。 37        var z = y.ToList().GroupBy(x => new {x.TdfkName, x.KenchoName} 38             .Select(x => new ChubuViewModel.ChubuInfoRow 39         { 40           TdfkName = a.Key.Tdfk_nm, 41           KenchoName = a.Key.Kencho_nm, 42           MeisanName = string.Join("、", a.Select(b => b.Meisan_nm)) 43         }).ToList(); 44 45      } 46    } 47  } 48}

以上の形で自己解決となりました。
(クエリ構文で書こうとするとVSでエラーが出てしまうため、メソッド構文で落ち着きました)

今回回答いただいた記述や添付いただいたリンクは、個人のスキルアップにおいて非常にためになりました。
ご回答いただいたみなさま、ありがとうございました。

投稿2021/02/08 13:52

okanegahosii

総合スコア14

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

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

退会済みユーザー

退会済みユーザー

2021/02/08 22:15 編集

> 以上の形で自己解決となりました。 自己解決とは言うより回答者の回答を自分ケースにに書き直しただけのように見えますけど。 > GroupBy(x => new {x.TdfkName, x.KenchoName} ) が抜けてるような気がしますけどそこは置いといて・・・ 都道府県だけでグループ化すればよいのでは? 県庁所在地が都道府県の中に複数あることはないのですから。 > クエリ構文で書こうとするとVSでエラーが出てしまうため、メソッド構文で落ち着きました なぜですか? それから、Aggregate を使わなかったのはどういう理由でしょう?
okanegahosii

2021/02/14 12:54

>都道府県だけでグループ化すればよいのでは? 県庁所在地が都道府県の中に複数あることはないのですから。 確かに仰る通りですが、都道府県と県庁所在地両方でグループ化しても問題はないはずです。 > なぜですか? エラーが出た理由は忘れましたが、メソッド構文で落ち着かせた理由はスケジュール上の都合です。 > それから、Aggregate を使わなかったのはどういう理由でしょう? 使わずに済むなら使いたくなかったからです。
退会済みユーザー

退会済みユーザー

2021/02/14 13:05 編集

もうどうでもいいですけど、とにかく何にせよ「自己解決」ではありません。自己解決というのは、回答が解決の役に立たなくて、自分で解決策を見つけた時のみのそういう言い方をすべき。これを自己解決と言うのは回答者にあまりに失礼。言い方に気をつけてください。
guest

0

画像の「現状」はコードの変数 y に取得できているので、それを Linq で加工して画像の「完成イメージ」のオブジェクトを作るということでいいということですので、やり方のサンプルを貼っておきます。以前、相手が DataTable で作ったものなですが、質問の List<T> が相手でも、グループ化して Aggregate を使うというポイントは同じです。

DataTable datatable = new DataTable(); datatable.Columns.Add(new DataColumn("Name", typeof(string))); datatable.Columns.Add(new DataColumn("Date", typeof(DateTime))); DataRow datarow; datarow = datatable.NewRow(); datarow["Name"] = "サッカー"; datarow["Date"] = new DateTime(2019, 9, 1); datatable.Rows.Add(datarow); datarow = datatable.NewRow(); datarow["Name"] = "野球"; datarow["Date"] = new DateTime(2019, 9, 1); datatable.Rows.Add(datarow); datarow = datatable.NewRow(); datarow["Name"] = "柔道"; datarow["Date"] = new DateTime(2019, 10, 1); datatable.Rows.Add(datarow); datarow = datatable.NewRow(); datarow["Name"] = "テニス"; datarow["Date"] = new DateTime(2019, 9, 2); datatable.Rows.Add(datarow); datarow = datatable.NewRow(); datarow["Name"] = "バレー"; datarow["Date"] = new DateTime(2019, 9, 2); datatable.Rows.Add(datarow); datarow = datatable.NewRow(); datarow["Name"] = "卓球"; datarow["Date"] = new DateTime(2019, 9, 3); datatable.Rows.Add(datarow); datarow = datatable.NewRow(); datarow["Name"] = "野球"; datarow["Date"] = new DateTime(2019, 9, 3); datatable.Rows.Add(datarow); datarow = datatable.NewRow(); datarow["Name"] = "バレー"; datarow["Date"] = new DateTime(2019, 9, 3); datatable.Rows.Add(datarow); datarow = datatable.NewRow(); datarow["Name"] = "剣道"; datarow["Date"] = new DateTime(2019, 11, 3); datatable.Rows.Add(datarow); Console.WriteLine("----Aggregate2----------------"); var query2 = from d in datatable.AsEnumerable() group d by d.Field<DateTime>("Date") into g select new { Date = g.Key, Name = g.Select(x => x.Field<string>("Name")).Aggregate((a,b) => a + "," + b) }; foreach (var x in query2) { Console.WriteLine($"Date: {x.Date.ToShortDateString()}, Name: {x.Name}"); } // 結果は: // Date: 2019/09/01, Name: サッカー,野球 // Date: 2019/10/01, Name: 柔道 // Date: 2019/09/02, Name: テニス,バレー // Date: 2019/09/03, Name: 卓球,野球,バレー // Date: 2019/11/03, Name: 剣道

投稿2021/02/06 00:39

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問