Visual Basic 中学校 掲示板 投稿の管理
タグのない投稿を抽出
統計
RSS
Visual Basic 中学校
投稿一覧
複数のデータテーブルやコレクションのデータを並べ替えたり、絞り込みたいです。
この投稿へのリンク
https://keijiban.umayadia.com/ThreadDetail.aspx?ThreadId=30286#CommentId83051
この投稿の削除
削除パスワード
削除する
コメント本文
投稿者
魔界の仮面弁士
 (社会人)
投稿日時
2017/9/13 12:03:40
> LINQ自体、あまり詳しくありませんが。。。
LINQ には、SQL チックな記述が魅力的な「クエリ構文」と
Dim q = From entry In collection Where …
より強力な「メソッド構文」による形式の 2 種類があります。
Dim q = collection.Where(Function(entry) …)
LINQ の機能によっては、メソッド構文でないと呼び出せないものもあります。
(一方、クエリ構文で呼び出せる機能は、すべて同等のメソッド構文が存在します)
> データテーブルをLIST等のコレクションにコンバートしてから、条件による並べ替えや絞り込みを行おうと考えています。
その必要はありません。
DataTable.Rows は DataRow のコレクションなので、LINQ でも処理できますよ。
それに DataView も、DataRowView のコレクションですしね。
http://msdn.microsoft.com/ja-jp/library/bb386977.aspx
http://msdn.microsoft.com/ja-jp/library/bb386921.aspx
また、DataTable を LINQ で抽出した場合は、
Dim resultTable As DataTable = q.CopyToDataTable()
のように、抽出結果を DataTable として受け取ることもできます。
> ①動的な複数の検索条件による絞り込み
「複数の検索条件」というのが、SQL で言うところの
WHERE TBL.ID IN ('01', '03', '06', '10', '15')
のような物だとしたら、
Dim data As String() = {"01", "03", "06", "10", "15"}
Dim q = From r In dataTable1 Where data.Contains(r.Field(Of String)("ID"))
のように、Contains 拡張メソッドを使うことができます。
「複数の検索条件」というのが、SQL で言うところの
WHERE TBL.COL1 = 'A'
AND TBL.COL2 = 'B'
AND TBL.COL3 = 'C'
のようなものだとしたら、
Dim p1 = "A", p2 = "B", p3 = "C"
Dim q = dataTable1.AsEnumerable()
q = q.Where(Function(r) r("COL1") = p1)
q = q.Where(Function(r) r("COL2") = p2)
q = q.Where(Function(r) r("COL3") = p3)
のように、パイプラインを連ねることで記述できます。
しかし「複数の検索条件」というのが、SQL で言うところの
WHERE TBL.ID = '01'
OR TBL.ID = '02'
OR TBL.COL1 = 'A'
OR TBL.COL2 = 'B'
OR TBL.COL3 = 'C'
のようなものになると、これは少々厄介です。
(案1) OR 条件を反転させて AND 条件に変換する。(ド・モルガンの法則)
'Not And な条件で抽出
Dim qNotAnd = dataTable1.AsEnumerable()
qNotAnd = qNotAnd.Where(Function(r) r("ID") <> "01")
qNotAnd = qNotAnd.Where(Function(r) r("ID") <> "02")
qNotAnd = qNotAnd.Where(Function(r) r("COL1") <> "A")
qNotAnd = qNotAnd.Where(Function(r) r("COL2") <> "B")
qNotAnd = qNotAnd.Where(Function(r) r("COL3") <> "C")
'最後にそれを元のコレクションから取り除く
Dim q = dataTable1.AsEnumerable().Except(qNotAnd)
(案2) ラムダ式による OR 条件のリストを Any に渡す。
'検索条件のコレクションを用意しておく
Dim OrConditions As New List(Of Func(Of DataRow, Boolean))()
OrConditions.Add(Function(r) r("ID") = "01")
OrConditions.Add(Function(r) r("ID") = "02")
OrConditions.Add(Function(r) r("COL1") = "A")
OrConditions.Add(Function(r) r("COL2") = "B")
OrConditions.Add(Function(r) r("COL3") = "C")
'いずれかの条件を満たすものを抽出
Dim q = From r In dataTable1 Where OrConditions.Any(Function(m) m(r))
(案3) System.Linq.Expressions.Expression を使う。
長くなりそうなのでサンプルは省略。
強力な機能ではあるのですが、式ツリーの構築に手間がかかります。
> ②絞り込みや並べ替えに必要な情報が足りないので、
> 例えばLIST_BのNAMEという項目に紐づけようと、LIST_CをJOINしようと
> Join C In LIST_C On B.NAME Equals C.NAME
> としたのですが、上手く結合した結果が返却されませんでした。
「必要な情報が足りない」というのは、どういう意味でしょうか?
それぞれの LIST がどういう内容になっていて、
それをどのように結合したいのか、具体的に書いてもらえれば、
サンプルを提示できるかもしれません。