VB.NETでDataSetをJSONからクラスに変換

Visual StudioにJSONからクラスを生成する機能があるようです。（以下リンク参照）

【C#】【Visual Studio】Visual Studio でJSONからクラスを生成
http://kageura.hatenadiary.jp/entry/2015/07/10/210000

ということはDataSetをJSONに変換してそこからクラスを生成することで

DataSet → JSON → クラス
クラス → JSON → DataSet

のような相互変換が可能になるんじゃないかと思い試してみました。

#環境
Windows 7 Professional SP1 64bit
Visual Studio 2017 Community
Newtonsoft.Json 10.0.2 ※NuGetでソリューションにパッケージを追加して下さい

#プロジェクト作成
今回はVisual BasicのWindowsフォームアプリケーションで作成しました。

フォームにボタンとデータグリッドを配置します。
![aaa.png](https://qiita-image-store.s3.amazonaws.com/0/112075/da0d5b05-916e-0d5b-9b7f-a8e372547166.png)

変換元のデータセットを作成します。
![bbb.png](https://qiita-image-store.s3.amazonaws.com/0/112075/38211991-4bde-af18-7846-e7c094760e98.png)

各カラムの型は以下の通りです。
DataColumn1: Integer
DataColumn2: String
DataColumn3: Datetime

#DataSetをJSONに変換
ボタンクリックイベントにDataSetをJSONに変換するプログラムを作成します。
DataTableをシリアライズしてJSONに変換します。

```vbnet:Form.vb
Imports Newtonsoft.Json

Public Class Form1
    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        ''変換元データセットを初期化
        Dim srcds As New DataSet1
        For i As Integer = 1 To 5
            Dim row As DataSet1.DataTable1Row = srcds.DataTable1.NewDataTable1Row
            row.DataColumn1 = i.ToString
            row.DataColumn2 = "データ" + i.ToString
            row.DataColumn3 = Date.Now
            srcds.DataTable1.AddDataTable1Row(row)
        Next

        ''データテーブルをJSONに変換 ※DataTableをシリアライズする
        Dim dataset_json As String = JsonConvert.SerializeObject(srcds.DataTable1, Formatting.Indented)
        Debug.WriteLine(dataset_json)
    End Sub
End Class
```

このまま実行すると出力(デバック)にJSONが出力されます。

```json:出力(デバック)
[
  {
    "DataColumn1": 1,
    "DataColumn2": "データ1",
    "DataColumn3": "2017-06-12T21:55:14.0343035"
  },
  {
    "DataColumn1": 2,
    "DataColumn2": "データ2",
    "DataColumn3": "2017-06-12T21:55:14.0373039"
  },
  {
    "DataColumn1": 3,
    "DataColumn2": "データ3",
    "DataColumn3": "2017-06-12T21:55:14.0373039"
  },
  {
    "DataColumn1": 4,
    "DataColumn2": "データ4",
    "DataColumn3": "2017-06-12T21:55:14.0373039"
  },
  {
    "DataColumn1": 5,
    "DataColumn2": "データ5",
    "DataColumn3": "2017-06-12T21:55:14.0373039"
  }
]
```

#JSONからクラスを作成
出力されたJSONをコピーして形式を指定して貼り付けから「JSONをクラスとして貼り付ける」を選択すると以下のようなクラスが作成される。

```vbnet:Class1.vb
Public Class Rootobject
    Public Property Property1() As Class1
End Class

Public Class Class1
    Public Property DataColumn1 As Integer
    Public Property DataColumn2 As String
    Public Property DataColumn3 As Date
End Class
```

このままだと使いにくいので次のように変更しました。
Rootobject → DataTable1
Property1() As Class1 → Rows As DataTable1Row()  ※カッコを型の後ろに
Class1 → DataTable1Row
Namespace Model 追記

```vbnet:Class1.vb
Namespace Model

    Public Class DataTable1
        Public Property Rows As DataTable1Row()
    End Class

    Public Class DataTable1Row
        Public Property DataColumn1 As Integer
        Public Property DataColumn2 As String
        Public Property DataColumn3 As Date
    End Class

End Namespace
```

#JSONからクラスに変換
作成したボタンクリックイベントに以下のコードを追加します。
model変数が上のクラスになります。JSONをListオブジェクトにデシリアライズして格納します。

```vbnet:Form.vb
        ''JSONをクラスに変換 ※クラスは出力したJSONを貼り付けて作成し、Listにデシリアライズする
        Dim model As New Model.DataTable1
        Dim rows As List(Of Model.DataTable1Row) = JsonConvert.DeserializeObject(Of List(Of Model.DataTable1Row))(dataset_json)
        model.Rows = rows.ToArray
```

ここまででDataSet→JSON→クラスまで変換できました。

#クラスからDataSetに戻す
クラス(model.Rows)をシリアライズしてJSONに変換し、JSONをDataTableに変換します。
最終的に次のようなプログラムになります。

```vbnet:Form.vb
Imports Newtonsoft.Json

Public Class Form1
    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        ''変換元データセットを初期化
        Dim srcds As New DataSet1
        For i As Integer = 1 To 5
            Dim row As DataSet1.DataTable1Row = srcds.DataTable1.NewDataTable1Row
            row.DataColumn1 = i.ToString
            row.DataColumn2 = "データ" + i.ToString
            row.DataColumn3 = Date.Now
            srcds.DataTable1.AddDataTable1Row(row)
        Next

        ''データテーブルをJSONに変換 ※DataTableをシリアライズする
        Dim dataset_json As String = JsonConvert.SerializeObject(srcds.DataTable1, Formatting.Indented)
        Debug.WriteLine(dataset_json)

        ''JSONをクラスに変換 ※クラスは出力したJSONを貼り付けて作成し、Listにデシリアライズする
        Dim model As New Model.DataTable1
        Dim rows As List(Of Model.DataTable1Row) = JsonConvert.DeserializeObject(Of List(Of Model.DataTable1Row))(dataset_json)
        model.Rows = rows.ToArray

        ''クラスをJSONに変換 ※配列(Rows)をシリアライズする
        Dim model_json As String = JsonConvert.SerializeObject(model.Rows, Formatting.Indented)
        Debug.WriteLine(model_json)

        ''JSONをデータテーブルに変換 ※DataTableにデシリアライズする
        Dim dt As DataSet1.DataTable1DataTable = JsonConvert.DeserializeObject(Of DataSet1.DataTable1DataTable)(model_json)

        ''変換先データセットをグリッドに表示 ※データテーブルの内容をコピー
        Dim destds As New DataSet1
        For Each row As DataSet1.DataTable1Row In dt.Rows
            destds.DataTable1.ImportRow(row)
        Next
        DataGridView1.DataSource = destds.DataTable1
    End Sub
End Class
```

これでクラス→JSON→DataSetに変換できました。

#実行
実行してグリッドにデータが表示されたら完成です。
デバッガで停止しながら動作を確認するとわかりやすいと思います。

![ccc.png](https://qiita-image-store.s3.amazonaws.com/0/112075/88960109-c198-c79b-f7e1-bb9a1c512ead.png)