作成日: 2015/12/03, 更新日: 2015/12/03
型無し DataRow をデータクラスに変換してみた( VB.NET 版)
うーん、困った。
- Entity Framework が主流と言われる昨今ですが、今更 DataRow のお話です。
- ずうっと、DataSet を使い続けてきた私にとって、簡単に準備できるテストデータは DataSet でこしらえることが多い日々です。 DataSet を使うなら、型無し DataSet ではなく型付 DataSet の方が、扱いが楽ですよね。 でも皆さんが言うように、型付 DataSet は何でもかんでも搭載しているし、壊れることもあるし、よろしくないよねーというのも分かります。
- 普段簡単に扱うなら、作るのが楽な 型無し DataSet なわけですが、使うときは、やっぱりフィールド指定が面倒くさい面倒くさい。 インテリセンスでさくっといかないものかと、あれこれ考えました。
スポンサーリンク
対処案その1、匿名型のデータクラスに変換して使う。
- この対処案は、匿名型とオブジェクト初期化子と型推論を使ったものです。
Dim dt As New DataTable("SampleTable") dt.Columns.AddRange(New DataColumn() { New DataColumn("ID", GetType(Integer)), New DataColumn("Name", GetType(String)) }) dt.Rows.Add(New Object() {1, "aaa"}) dt.Rows.Add(New Object() {2, "bbb"}) dt.Rows.Add(New Object() {3, "ccc"}) For Each row As DataRow In dt.Rows Dim user = New With {.ID = row.Field(Of Integer)("ID"), .Name = row.Field(Of String)("Name")} Console.WriteLine("ID = {0}, Name = {1}", user.ID, user.Name) Next
スポンサーリンク
対処案その2、定義した型のデータクラスに変換して使う。
- 探しているうちに、山本大さんの記事を見つけて、おーこれだー!という結論になりました。 つまり、変換処理は自動的に行うのですが、変換後のデータクラスは、あらかじめ定義しておいてね。という仕様です。 本当は、あらかじめ定義しなくても、リフレクションとDataRow.DataTable.DataColumns 見て、 変換後のデータクラスを自動生成したかったので、なんとかならないかなーと考えていたんですが、 なんとかなりませんでした><。
- ちなみに対応策は、リフレクションとジェネリックと拡張メソッドの知識を持っている前提な話になりますが、 別によく分からなくてもいいような気もします。面倒見てあげる部分は一回作ったら放置で良いし、使い方の部分は、見たら分かりそうな感じかなと思います。
Imports System.Runtime.CompilerServices Imports System.Reflection Module DataRowExtensions <Extension()> Public Function GetRowData(Of TClass As New)(target As DataRow) As TClass Dim resultData As New TClass Dim t As Type = resultData.GetType Dim pis() As PropertyInfo = t.GetProperties For Each pi As PropertyInfo In pis pi.SetValue(resultData, target(pi.Name)) Next Return resultData End Function End Module
' DataTable に対応するデータクラスの定義 Class MemberData Public Property ID As Integer = 0 Public Property Name As String = String.Empty End Class
Dim dt As New DataTable("SampleTable") dt.Columns.AddRange(New DataColumn() { New DataColumn("ID", GetType(Integer)), New DataColumn("Name", GetType(String)) }) dt.Rows.Add(New Object() {1, "aaa"}) dt.Rows.Add(New Object() {2, "bbb"}) dt.Rows.Add(New Object() {3, "ccc"}) For Each row As DataRow In dt.Rows Dim user As MemberData = row.GetRowData(Of MemberData)() Console.WriteLine("ID = {0}, Name = {1}", user.ID, user.Name) Next
スポンサーリンク