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

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

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

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

LINQ

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

WPF

Windows Presentation Foundation (WPF) は、魅力的な外観のユーザー エクスペリエンスを持つ Windows クライアント アプリケーションを作成するための次世代プレゼンテーション システムです

Q&A

解決済

3回答

5694閲覧

LINQでJOINした全てのカラムを一度にSELECTしたい

elvis

総合スコア29

C#

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

LINQ

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

WPF

Windows Presentation Foundation (WPF) は、魅力的な外観のユーザー エクスペリエンスを持つ Windows クライアント アプリケーションを作成するための次世代プレゼンテーション システムです

0グッド

0クリップ

投稿2018/06/18 15:10

編集2018/06/19 04:08

###実現したいこと
2つのDataTableをLINQでJOINして、JOINした全ての列をSELECTしたいのですが、
上手く実現できません。一つずつ列を指定する必要があるのでしょうか。
どうかご教示ください。

環境:
visual studio 2013, c#, wpf,
.net Framework4.5
windows7

SQLでしたら以下のように「*」で全列をSELECTする形になります。

SQL

1SELECT 2 fam.* 3 ,per.* 4FROM dtFamily AS fam 5 INNER JOIN dtPerson AS per 6 ON fam.familyId = per.familyId

###現状

クエリ構文ならびにメソッド構文でJOINは出来てると思います。
(私見ですが)

###仕掛中のコード

C#

1 //家族テーブル作成 2 DataTable dtFamily = new DataTable(); 3 dtFamily.Columns.Add("familyId", typeof(int)); 4 dtFamily.Columns.Add("familyName", typeof(string)); 5 dtFamily.Rows.Add(0, "ishikawa"); 6 dtFamily.Rows.Add(1, "yamada"); 7 dtFamily.Rows.Add(2, "kondo"); 8 dtFamily.Rows.Add(3, "tanaka"); 9 10 //個人テーブル作成  11 DataTable dtPerson = new DataTable(); 12 dtPerson.Columns.Add("familyId", typeof(int)); 13 dtPerson.Columns.Add("personId", typeof(int)); 14 dtPerson.Columns.Add("personName", typeof(string)); 15 dtPerson.Rows.Add(0, 0, "takeo"); 16 dtPerson.Rows.Add(0, 1, "ruri"); 17 dtPerson.Rows.Add(0, 2, "takeshi"); 18 dtPerson.Rows.Add(1, 3, "tarou"); 19 dtPerson.Rows.Add(1, 4, "hanako"); 20 dtPerson.Rows.Add(1, 5, "taroko"); 21 dtPerson.Rows.Add(2, 6, "takuya"); 22 dtPerson.Rows.Add(2, 7, "chiemi"); 23 dtPerson.Rows.Add(3, 8, "kaito"); 24 //DataGrid1.ItemsSource = dt.DefaultView; 25 26 //メソッド構文 27 var methodQ = dtPerson.AsEnumerable().Join( 28 dtFamily.AsEnumerable(), 29 f => f["familyId"], 30 p => p["familyId"], 31 (p, f) => new 32 { 33 FamilyName = f["familyName"], 34 PersonName = p["personName"] 35 }); 36 DataGrid1.ItemsSource = methodQ; 37 38 //クエリ構文 39 var queryQ = 40 from p in dtPerson.AsEnumerable() 41 join f in dtFamily.AsEnumerable() 42 on p["familyId"] equals f["familyId"] 43 select new { 44 FamilyName = f["familyName"] 45 ,PersonName = p["personName"]}; 46 DataGrid2.ItemsSource = queryQ; 47

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

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

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

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

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

guest

回答3

0

ベストアンサー

提示コードでは、匿名クラスの{ string, string}が返されますが、その理由は

C#

1(p, f) => new 2{ 3 FamilyName = f["familyName"], 4 PersonName = p["personName"] 5} 6//とか 7select new { 8 FamilyName = f["familyName"] 9 ,PersonName = p["personName"]};

と文字列に限定してSelectを書いているためですよね?

C#

1(p, f) => new { FamilyInfo = f, PersonInfo = p}

みたいな返し方をすれば、SQLで言うところの、

fam.* ,per.*

に相当することはできると思います(使うときにどのカラムを取るかを指定できる)。

確かに、fam.*, per.*としたときのような出力にはなりませんが、そこは言語と用途の違いじゃないかと思います。

投稿2018/06/19 01:16

papinianus

総合スコア12705

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

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

elvis

2018/06/19 07:52

ご教示いただいた通りに記述すると、DataRaw型でデータを取得することが出来ました。 ご回答に感謝いたします。
guest

0

以下のようにしてはいかがですか? 質問者さんの開発環境(OS, .NET のバージョンなど・・・質問に書いてくださいね)が不明なので同じにできるかどうかわかりませんが、Windows 10 の .NET 4.6.1 のコンソールアプリで、下のコメントの通りの結果になります。

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Data; using System.Data.SqlClient; namespace ConsoleAppDataTableJoinByLinq { class Program { static void Main(string[] args) { //家族テーブル作成 DataTable dtFamily = new DataTable(); dtFamily.Columns.Add("familyId", typeof(int)); dtFamily.Columns.Add("familyName", typeof(string)); dtFamily.Rows.Add(0, "ishikawa"); dtFamily.Rows.Add(1, "yamada"); dtFamily.Rows.Add(2, "kondo"); dtFamily.Rows.Add(3, "tanaka"); //個人テーブル作成  DataTable dtPerson = new DataTable(); dtPerson.Columns.Add("familyId", typeof(int)); dtPerson.Columns.Add("personId", typeof(int)); dtPerson.Columns.Add("personName", typeof(string)); dtPerson.Rows.Add(0, 0, "takeo"); dtPerson.Rows.Add(0, 1, "ruri"); dtPerson.Rows.Add(0, 2, "takeshi"); dtPerson.Rows.Add(1, 3, "tarou"); dtPerson.Rows.Add(1, 4, "hanako"); dtPerson.Rows.Add(1, 5, "taroko"); dtPerson.Rows.Add(2, 6, "takuya"); dtPerson.Rows.Add(2, 7, "chiemi"); dtPerson.Rows.Add(3, 8, "kaito"); var query = from p in dtPerson.AsEnumerable() join f in dtFamily.AsEnumerable() on p.Field<int>("familyId") equals f.Field<int>("familyId") select new { FamilyId = f.Field<int>("familyId"), FamilyName = f.Field<string>("familyName"), PersonId = p.Field<int>("personId"), PersonName = p.Field<string>("personName") }; foreach (var item in query) { Console.WriteLine("FamiktyId: {0}, FamilyName: {1}, PersonId: {2}, PersonName: {3}", item.FamilyId, item.FamilyName, item.PersonId, item.PersonName); } // 結果は: // FamiktyId: 0, FamilyName: ishikawa, PersonId: 0, PersonName: takeo // FamiktyId: 0, FamilyName: ishikawa, PersonId: 1, PersonName: ruri // FamiktyId: 0, FamilyName: ishikawa, PersonId: 2, PersonName: takeshi // FamiktyId: 1, FamilyName: yamada, PersonId: 3, PersonName: tarou // FamiktyId: 1, FamilyName: yamada, PersonId: 4, PersonName: hanako // FamiktyId: 1, FamilyName: yamada, PersonId: 5, PersonName: taroko // FamiktyId: 2, FamilyName: kondo, PersonId: 6, PersonName: takuya // FamiktyId: 2, FamilyName: kondo, PersonId: 7, PersonName: chiemi // FamiktyId: 3, FamilyName: tanaka, PersonId: 8, PersonName: kaito } } }

投稿2018/06/19 03:32

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

elvis

2018/06/19 07:56 編集

ご丁寧に回答いただき感謝申し上げます。 以下のように列を指定するのではなく、 一発で全列をSELECTできないか思案しております。 サンプルテーブルのような少ない列数だといいのですが、 列数が増えてくると大変な作業になりますので。。。 select new { FamilyId = f.Field<int>("familyId"), FamilyName = f.Field<string>("familyName"), PersonId = p.Field<int>("personId"), PersonName = p.Field<string>("personName") };
elvis

2018/06/19 07:57

以下のようにDataRowを返すことで、 実現できました。 (f, p) => { DataRow row = dtResult.NewRow(); row.ItemArray = p.ItemArray.Concat(f.ItemArray).ToArray(); dtResult.Rows.Add(row); return row;              })).ToArray();
guest

0

上手く実現できません。

その時のエラーメッセージが表示されていれば質問に載せましょう。エラーメッセージでググれば自分で解決できるかも?

SQL

1SELECT 2 fam.* 3 ,per.* 4FROM dtFamily AS fam 5 INNER JOIN dtPerson AS per 6 ON fam.familyId = per.familyId

ではfamilyIdがダブるのでコンピュータはどちらのfamilyIdか困ってしまいます。

SQL

1SELECT 2 fam.* 3 ,per.personId 4 ,per.personName 5FROM dtFamily AS fam 6 INNER JOIN dtPerson AS per 7 ON fam.familyId = per.familyId

とすることでper.familyIdを除いてSELECTすることでダブりを解消しては?

投稿2018/06/18 19:08

Orlofsky

総合スコア16415

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

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

elvis

2018/06/19 03:05

ご回答ありがとうございます。 早速、試してみます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問