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

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

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

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

VB.NET

Microsoft Visual Basic .NETのことで、Microsoft Visual Basic(VB6)の後継。 .NET環境向けのプログラムを開発することができます。 現在のVB.NETでは、.NET Frameworkを利用して開発を行うことが可能です。

Q&A

解決済

1回答

11007閲覧

LINQを使ったデータテーブルからの抽出について

conn_e

総合スコア1

LINQ

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

VB.NET

Microsoft Visual Basic .NETのことで、Microsoft Visual Basic(VB6)の後継。 .NET環境向けのプログラムを開発することができます。 現在のVB.NETでは、.NET Frameworkを利用して開発を行うことが可能です。

0グッド

0クリップ

投稿2020/09/18 13:40

編集2020/09/19 00:19

開発環境

Windows10
VisualStudio 2017
VB.NET
.Net Framework 4.6.2

前提・実現したいこと

LINQを使い、データテーブルから条件に合致するデータを抽出したいと考えています。
例として下のテストデータを例に詳細を書きます。

KEY(STRING)CODE1(STRING)CODE2(STRING)VALUE(STRING)
10010テスト1-1
20011テスト1-2
30020テスト2-1
40021テスト2-2
50030テスト3-1
60031テスト3-2

上記のようなデータから、CODE1とCODE2を条件にデータの抽出を行います。
具体的な抽出条件は下記のとおりです。

・CODE1が「001」の場合:
CODE1が「001」のデータを取得

・CODE1が「002」の場合:
CODE1が「002」かつ、CODE2が「0」のデータを取得

・CODE1が「003」の場合:
CODE1が「003」かつ、CODE2が「0以上」のデータを取得

プログラム

VB.NET

1'検索条件となるCODE1 2'searchConditionの中身は動的に変わることを想定 3'"001"だけのこともあれば"001,002,003"の場合もある 4Dim searchCondition() As String = New String() {"001", "003"} 5Dim dt As Datatable = 前提・実現したいことに記載したデータ 6 7Dim linq = From row In dt.AsEnumerable 8 Where 1 = 1 9 10For Each str As String In searchCondition 11 Select Case str 12 Case "001" 13 linq = linq.Where(Function(row) row("CODE1") = str) 14 Case "002" 15 linq = linq.Where(Function(row) row("CODE1") = str And row("CODE2") = 0) 16 Case "003" 17 linq = linq.Where(Function(row) row("CODE1") = str And row("CODE2") >= 0) 18Next 19

期待値・実行結果

■期待値
KEY=1、KEY=2、KEY=6のデータを抽出したい
(row("CODE1") = str Or (linq.Where(Function(row) row("CODE1") = str And row("CODE2") >= 0))

■実行結果
CODE1=001のWhere句とCODE1=003のWhere句がAnd条件となってしまい抽出結果0件
(row("CODE1") = str And (linq.Where(Function(row) row("CODE1") = str And row("CODE2") >= 0))

複数のWhere句が作られた場合に、それらをOr条件で実行したいと考えています。

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

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

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

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

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

退会済みユーザー

退会済みユーザー

2020/09/18 14:22

開発環境ぐらいは書きましょう
退会済みユーザー

退会済みユーザー

2020/09/19 00:09 編集

VB.NET のタグをつけてください。 DataTable の各列の型を質問欄を編集して追記してください。 質問者さんの書いたコードの実行結果はどうなるのか、どこがどのように期待と異なるのかを質問欄を編集して追記してください。 > CODE1が「003」かつ、CODE2が「0以上」のデータを取得 だけが問題で、その ling だけ分かれば解決するように見えますが、そうなんですか? ・・・と思ったけど違うみたいですね。 Or でつなぐ? どういうことか、期待する結果を具体的に書くなどして説明できませんか?
退会済みユーザー

退会済みユーザー

2020/09/19 00:54

抽出条件は searchCondition の文字列の配列で、その組み合わせは以下の 7 通りあって、 "001" "002" "003" "001", "002" "001", "003" "002", "003" "001", "002", "003" 例えば "001", "003" の場合は、 CODE1が「001」のデータ と CODE1が「003」かつ、CODE2が「0以上」のデータ を linq に取得するということですか?
conn_e

2020/09/19 01:03

はい、そうです
退会済みユーザー

退会済みユーザー

2020/09/19 01:36

List<DataRow> 型にして良いなら List<T>.AddRange メソッドを使って追加していくという方法がありますが、それでいいですか?
退会済みユーザー

退会済みユーザー

2020/09/19 02:07

List<DataRow> 型にしなくても(EnumerableRowCollection<DataRow> 型のままでも)Concat を使って可能でした。後でその案を回答欄に書いておきます。
guest

回答1

0

ベストアンサー

抽出条件は searchCondition の文字列の配列で、その組み合わせは以下の 7 通りあって、

"001"
"002"
"003"
"001", "002"
"001", "003"
"002", "003"
"001", "002", "003"

そして、例えば searchCondition の中身が "001", "003" の場合は、

(1) CODE1が「001」のデータ

(2) CODE1が「003」かつ、CODE2が「0以上」のデータ

をまとめて EnumerableRowCollection<DataRow> オブジェクトとして取得したいということと理解してレスします。

以下のように Concat メソッドを使って上の (1) と (2) の結果を連結すればできると思います。コードは C# ですので注意してください。

// CODE1が「001」の場合: CODE1が「001」のデータを取得 var linq = from row in dt.AsEnumerable() where row.Field<string>("CODE1") == "001" select row; // CODE1が「003」の場合: CODE1が「003」かつ、CODE2が「0以上」のデータを取得 var linq2 = from row in dt.AsEnumerable() where row.Field<string>("CODE1") == "003" && row.Field<string>("CODE2").CompareTo("0") > 0 select row; var linq3 = linq.Concat(linq2); foreach (var x in linq3) { Console.WriteLine($"{x["KEY"]}, {x["CODE1"]}, {x["CODE2"]}, {x["VALUE"]}"); }

結果は:

1, 001, 0, テスト1-1
2, 001, 1, テスト1-2
6, 003, 1, テスト3-2

7 通り全部にどう対応するかは質問者さんの方で考えてください。

投稿2020/09/19 02:23

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問