【VB.NET】DataTable のMerge(マージ) 機能について

VB.NET
この記事は約15分で読めます。

概要

DataTable には Merge という便利な機能があります。Merge について説明します。

基本構文

テーブル1.Merge(テーブル2)

 

内容

マージするDataTabl に 存在しないカラムが追加されます。存在するとは対応するカラムの名前が無いと言う事です。
サンプルコードの例だと dt1 にある dc は追加されず、 dc2_2 のみが追加されます。

サンプルコードです。

Module Module1
    Sub Main()

        ' DataTable オブジェクト作成
        Dim dt1 As DataTable = New DataTable

        ' DataColumn オブジェクト作成
        Dim dc1_1 As DataColumn = New DataColumn("dc", GetType(Integer))
        Dim dc1_2 As DataColumn = New DataColumn("dc1_2", GetType(String))

        dt1.Columns.Add(dc1_1)
        dt1.Columns.Add(dc1_2)

        ' DataTable オブジェクト作成
        Dim dt2 As DataTable = New DataTable

        ' DataColumn オブジェクト作成
        Dim dc2_1 As DataColumn = New DataColumn("dc", GetType(Integer))
        Dim dc2_2 As DataColumn = New DataColumn("dc2_2", GetType(String))

        dt2.Columns.Add(dc2_1)
        dt2.Columns.Add(dc2_2)

        ' マージ前の確認
        For Each c In dt1.Columns
            Console.WriteLine(c.ToString) 'dc dc1_2
        Next

        For Each c In dt2.Columns
            Console.WriteLine(c.ToString) 'dc dc2_2
        Next

        ' マージ実行 カラム dc は両方にある
        dt1.Merge(dt2)

        ' マージ後の確認
        For Each c In dt1.Columns
            Console.WriteLine(c.ToString) 'dc dc1_2 dc2_2
        Next

        For Each c In dt2.Columns
            Console.WriteLine(c.ToString) 'dc dc2_2
        Next

    End Sub
End Module

 

カラム名は同じだがデータ型が違う場合

カラム名は同じだがデータ型が違う場合は System.Data.DataException が発生します。

Module Module1
    Sub Main()

        ' DataTable オブジェクト作成
        Dim dt1 As DataTable = New DataTable

        ' DataColumn オブジェクト作成
        Dim dc1_1 As DataColumn = New DataColumn("dc", GetType(Integer))
        Dim dc1_2 As DataColumn = New DataColumn("dc1_2", GetType(String))

        dt1.Columns.Add(dc1_1)
        dt1.Columns.Add(dc1_2)

        ' DataTable オブジェクト作成
        Dim dt2 As DataTable = New DataTable

        ' DataColumn オブジェクト作成
        Dim dc2_1 As DataColumn = New DataColumn("dc", GetType(String)) 'String型
        Dim dc2_2 As DataColumn = New DataColumn("dc2_2", GetType(String))

        dt2.Columns.Add(dc2_1)
        dt2.Columns.Add(dc2_2)

        ' マージ前の確認
        For Each c In dt1.Columns
            Console.WriteLine(c.ToString) 'dc dc1_2
        Next

        For Each c In dt2.Columns
            Console.WriteLine(c.ToString) 'dc dc2_2
        Next

        ' マージ実行
        dt1.Merge(dt2)

        ' マージ後の確認
        For Each c In dt1.Columns
            Console.WriteLine(c.ToString) 'dc dc1_2 dc2_2
        Next

        For Each c In dt2.Columns
            Console.WriteLine(c.ToString) 'dc dc2_2
        Next

    End Sub
End Module

 

ハンドルされていない例外: System.Data.DataException: .dc と .dc は競合するプロパティがあります : DataType プロパティの不一致
   場所 System.Data.Merger.MergeSchema(DataTable table)
   場所 System.Data.Merger.MergeTableData(DataTable src)
   場所 System.Data.Merger.MergeTable(DataTable src)
   場所 System.Data.DataTable.Merge(DataTable table, Boolean preserveChanges, MissingSchemaAction missingSchemaAction)
   場所 System.Data.DataTable.Merge(DataTable table)
   場所 ConsoleApplication1.Module1.Main() 場所 C:\workProjects\ConsoleApplication1\ConsoleApplication1\Module1.vb:行 34
続行するには何かキーを押してください . . .

 

マージ後にマージされたデータテーブルにカラムを追加してみる

マージ後は、相互に影響を与えません。

Module Module1
    Sub Main()

        ' DataTable オブジェクト作成
        Dim dt1 As DataTable = New DataTable

        ' DataColumn オブジェクト作成
        Dim dc1_1 As DataColumn = New DataColumn("dc", GetType(Integer))
        Dim dc1_2 As DataColumn = New DataColumn("dc1_2", GetType(String))

        dt1.Columns.Add(dc1_1)
        dt1.Columns.Add(dc1_2)

        ' DataTable オブジェクト作成
        Dim dt2 As DataTable = New DataTable

        ' DataColumn オブジェクト作成
        Dim dc2_1 As DataColumn = New DataColumn("dc", GetType(Integer))
        Dim dc2_2 As DataColumn = New DataColumn("dc2_2", GetType(String))

        dt2.Columns.Add(dc2_1)
        dt2.Columns.Add(dc2_2)

        ' マージ実行
        dt1.Merge(dt2)

        ' dt2にカラムを追加
        Dim dc2_3 As DataColumn = New DataColumn("dc2_3", GetType(String))
        dt2.Columns.Add(dc2_3)

        For Each c In dt1.Columns
            Console.WriteLine(c.ToString) 'dc dc1_2 dc2_2
        Next

        For Each c In dt2.Columns
            Console.WriteLine(c.ToString) 'dc dc2_2 dc2_3
        Next

    End Sub
End Module

 

レコード入れた状態でマージしてみる。

下記のようなレコードを各テーブルに登録した状態でマージしてみます。

テーブル1

dc dc1_2
1
2

テーブル2

dc dc2_2
1
3
Module Module1
    Sub Main()

        ' DataTable オブジェクト作成
        Dim dt1 As DataTable = New DataTable

        ' DataColumn オブジェクト作成
        Dim dc1_1 As DataColumn = New DataColumn("dc", GetType(Integer))
        Dim dc1_2 As DataColumn = New DataColumn("dc1_2", GetType(String))

        dt1.Columns.Add(dc1_1)
        dt1.Columns.Add(dc1_2)

        ' レコード追加
        dt1.Rows.Add(1, "あ")
        dt1.Rows.Add(2, "い")

        ' DataTable オブジェクト作成
        Dim dt2 As DataTable = New DataTable

        ' DataColumn オブジェクト作成
        Dim dc2_1 As DataColumn = New DataColumn("dc", GetType(Integer))
        Dim dc2_2 As DataColumn = New DataColumn("dc2_2", GetType(String))

        dt2.Columns.Add(dc2_1)
        dt2.Columns.Add(dc2_2)

        ' レコード追加
        dt2.Rows.Add(1, "A")
        dt2.Rows.Add(3, "B")

        ' マージ実行
        dt1.Merge(dt2)

        ' 出力 
        For Each r As DataRow In dt1.Rows
            For Each c As Object In r.ItemArray
                If c.Equals(DBNull.Value) Then
                    Console.Write(" ")
                Else
                    Console.Write(c)
                End If
                Console.Write(",")
            Next
            Console.WriteLine()
        Next

    End Sub
End Module
1,あ, ,
2,い, ,
1, ,A,
3, ,B,
続行するには何かキーを押してください . . .

4レコードになっていますね。

 

主キーを設定してマージしてみる

両方のテーブルに存在する dc を主キー設定します。

dt1.PrimaryKey = New DataColumn() {dt1.Columns("dc")}
Module Module1
    Sub Main()

        ' DataTable オブジェクト作成
        Dim dt1 As DataTable = New DataTable

        ' DataColumn オブジェクト作成
        Dim dc1_1 As DataColumn = New DataColumn("dc", GetType(Integer))
        Dim dc1_2 As DataColumn = New DataColumn("dc1_2", GetType(String))

        dt1.Columns.Add(dc1_1)
        dt1.Columns.Add(dc1_2)

        dt1.PrimaryKey = New DataColumn() {dt1.Columns("dc")}

        ' レコード追加
        dt1.Rows.Add(1, "あ")
        dt1.Rows.Add(2, "い")

        ' DataTable オブジェクト作成
        Dim dt2 As DataTable = New DataTable

        ' DataColumn オブジェクト作成
        Dim dc2_1 As DataColumn = New DataColumn("dc", GetType(Integer))
        Dim dc2_2 As DataColumn = New DataColumn("dc2_2", GetType(String))

        dt2.Columns.Add(dc2_1)
        dt2.Columns.Add(dc2_2)

        ' レコード追加
        dt2.Rows.Add(1, "A")
        dt2.Rows.Add(3, "B")

        ' マージ実行
        dt1.Merge(dt2)

        For Each r As DataRow In dt1.Rows

            For Each c As Object In r.ItemArray
                If c.Equals(DBNull.Value) Then
                    Console.Write(" ")
                Else
                    Console.Write(c)
                End If
                Console.Write(",")
            Next
            Console.WriteLine()
        Next

    End Sub
End Module
1,あ,A,
2,い, ,
3, ,B,
続行するには何かキーを押してください . . .

主キーである カラム dc が統合されて dc = 1 のレコードが1件になりました。

 

マージされる側に主キーを設定してみる。

dt2 側に主キーを設定してみます。

Module Module1
    Sub Main()

        ' DataTable オブジェクト作成
        Dim dt1 As DataTable = New DataTable

        ' DataColumn オブジェクト作成
        Dim dc1_1 As DataColumn = New DataColumn("dc", GetType(Integer))
        Dim dc1_2 As DataColumn = New DataColumn("dc1_2", GetType(String))

        dt1.Columns.Add(dc1_1)
        dt1.Columns.Add(dc1_2)

        ' DataTable オブジェクト作成
        Dim dt2 As DataTable = New DataTable

        ' DataColumn オブジェクト作成
        Dim dc2_1 As DataColumn = New DataColumn("dc", GetType(Integer))
        Dim dc2_2 As DataColumn = New DataColumn("dc2_2", GetType(String))

        dt2.Columns.Add(dc2_1)
        dt2.Columns.Add(dc2_2)

        ' マージされる側に主キーを設定
        dt2.PrimaryKey = New DataColumn() {dt2.Columns("dc")}

        ' 主キーの有無を確認
        Console.WriteLine(dt1.PrimaryKey.Length) '0

        ' マージ実行
        dt1.Merge(dt2)

        ' 主キーの有無を確認
        Console.WriteLine(dt1.PrimaryKey.Length) '1

    End Sub
End Module
0
1
続行するには何かキーを押してください . . .

主キー設定もマージされます。

コメント

タイトルとURLをコピーしました