メインメニューを開く

差分

型付DataSetに列挙型を取り込む

7,183 バイト追加, 2019年7月22日 (月) 13:23
ページの作成:「型付DataSetに列挙型(enum)を取り込む場合、色々な方法があると思うんだ。一番簡単に想像できるのは、DataSetデザイナーで特…」
型付DataSetに列挙型(enum)を取り込む場合、色々な方法があると思うんだ。一番簡単に想像できるのは、DataSetデザイナーで特定のテーブルの列の型を、ネームスペース含めて列挙型をしてしまうことなんだけど…。僕がやった限り、一回これをやってしまうとデータセットデザイナーが正しく開けなくなっちゃうんだよ。で、色々調べて・試してその結果たどり着いた(僕が)最善と思っている方法を紹介するよ。

== 考え方 ==
色々やった結果…実はDataSetに列挙型を取り込むこと自体を諦めたんだよ…(^_^;)でも、コード上で毎回キャストしたくはなかったんだ…。そこで注目したのは、自動生成される型付DataSetはpartialクラスってことなんだ…。つまり、DataSetの定義は「Int32」でしておいて、DataSetのpartialを作って、そのクラスに列挙型で出し入れできるプロパティを作ってしまおうって事なんだよ。

=== partialクラスってなに??? ===
partialクラスって言うのは、クラス定義を分割して定義している(ないしはできる)クラスのことを言うんだよ。たとえば、以下のようなクラスがあったとするよね…

<source lang="csharp">
namespace CommonCtrlLib
{
public class Class1
{
private Int32 m_field_A;

public Class1()
{
this.m_field_A = -1;
}

public Int32 field_A
{
get { return this.m_field_A; }
set { this.m_field_A = value; }
}

public String field_B
{
get { return this.m_field_A.ToString(); }
set { this.m_field_A = Int32.Parse(value); }
}
}
}
</source>

クラス内の定義って言うのはclass{}の中に記述しないといけないから、つまるところ1ファイルの中にすべて書かないといけないって事になっちゃうんだよね。でも、諸事情により別のファイルに書きたいときもあると思うんだ。自動生成されたDataSetのファイルなんかは特にそうで…自動生成されたファイルをカスタマイズしちゃうと、また自動生成したときにカスタマイズが消えちゃったりするんだ。そんなときに、自分のカスタマイズ部分だけ別のファイルに書ければ…ってことになるんだよ。

そんなときはclassをpartial型で定義するとできちゃうんだよ。

ファイル1
<source lang="csharp">
namespace TestLibrary
{
public partial class Class1
{
private Int32 m_field_A;

public Class1()
{
this.m_field_A = -1;
}

public Int32 field_A
{
get { return this.m_field_A; }
set { this.m_field_A = value; }
}
}
}
</source>
ファイル2
<source lang="csharp">
namespace TestLibrary
{
public partial class Class1
{
public String field_B
{
get { return this.m_field_A.ToString(); }
set { this.m_field_A = Int32.Parse(value); }
}
}
}
</source>

こうやって定義すると、2つのファイルに分かれているclass定義でも、1つのclassとして扱うことができるんだ。

== 型付DataSetの作成 ==
列挙型を取り込みたいって悩んでいる人には、このステップは用済みかもしれないけど一応書いておくね。VisualStudioを起動してプロジェクトを開いている前提で手順をあげるよ。

<ol>
<li>ソリューションエクスプローラーからDataSetを追加したいプロジェクトを右クリックする。</li>
<li>メニューから「追加」→「新しい項目」を選択する。</li>
<li>(C♯の)一覧からデータセットを選択し、名前に適当なファイル名を入れ、「追加」ボタンをクリックする。</li>
<li>デザイナーが開くので、ツールボックスからDataTableをデザイナーにドラッグアンドドロップしてテーブルを追加する。テーブル名は適当に変更する。</li>
<li>デザイナーのテーブルを右クリックして、「追加」→「列」を選択し、適当な列を追加する。</li>
<li>必要に応じてキーを設定する</li>
</ol>

ここで、列挙型を保存したい列の型を「System.Int32」に変更するんだよ。
デザイナーで列を選択すると、プロパティウインドウに列のプロパティが表示されるんだ。その中の「DataType」プロパティの値を「System.Int32」に変更するんだよ。

== partialクラスの追加 ==
partialクラスを追加する方法もインターネットを調べると色々出てくるんだけど…どうやらMicrosoftはこの方法を推奨しているみたいなんだよ。
<ol>
<li>データセットデザイナを表示する。</li>
<li>データセットデザイナの何も書かれていないところ(余白?)をダブルクリックする。</li>
<li>以下のようなコードが表示される(ネームスペースが「TestLibrary」で、データセットクラス名が「DataSet1」の場合)
<source lang="csharp">
namespace TestLibrary {


public partial class DataSet1 {
}
}
</source>
</li>
</ol>
これでDataSetのpartialクラスが追加されたんだよ。ソリューションエクスプローラーを見ても「xxxxx.xsd」ファイルの配下にこのpartialクラスのファイルが入っていて、見た目にもすっきりしていると思うんだ。

== partialクラスにメソッドを追加 ==
作成されたpartialクラスに列挙型で出し入れできる、プロパティを追加するよ。手順とかじゃなくて、追加したpartialクラスを以下の様に修正するんだよ。
;namespace:TestLibrary
;DataSet名:DataSet1
;DataTable名:DataTable1
;DataColumn名:DataColumn1
;列挙型名:e_Test

<source lang="csharp">
namespace TestLibrary {
public partial class DataSet1 {
partial class DataTable1Row
{
public e_Test EnumDataColumn1
{
get
{
return (e_Test)this.DataColumn1;
}
set
{
this.DataColumn1 = (Int32)value;
}
}
}
}
}
</source>

これで、列挙型で出し入れできるメソッドを追加することができたよ。もしWPFでバインドしたいときなどは、Int32で取り出すメソッド(この場合「DataColumn1」)でバインドすれば、特に悩むことなく実現できると思うんだ。

== 参考サイト ==
[https://msdn.microsoft.com/ja-jp/library/ms171896.aspx MSDN - 方法 : データセットの機能を拡張する]<br/>
[http://gushwell.ldblog.jp/archives/50810947.html Gushwell's C# Dev Notes - DataSetのカラムで列挙型を扱うには]

[[Category:C♯]]
[[Category:Dataset]]