.Netアプリで階層構造のマスタを扱うことになったため、あれこれ探していたら、どうやらSQLServer2008からはhierarcyid型という階層構造を使える型があることを知った
これは素晴らしい、とさっそく該当マスタテーブルにhierarcyid型を作成し、作ってみた
なお、作り方よくわからなかったので、
http://blogs.wankuma.com/kaya/archive/2008/03/19/128582.aspx
ここを参考にした
実際は.Netアプリ上で、その階層構造をTreeViewで表示しようと考える。よくありがちです。
さて、どこかにサンプルはないかとさまよっていたら素晴らしいものを発見
Loading a TreeView using HierarchyID
http://www.codeproject.com/Articles/37038/Loading-a-TreeView-using-HierarchyID
そのまんまでした。
一応DLしてみたところ動きます。ただ、このサンプルはXMLデータから取得していましたが、私が作りたかったのはSQLServerからのテーブルデータだったのでちょっと変更をすることに
hierarcyid型を持つテーブルをWebサービス上のDatasetとして作成し、.Netアプリから呼び出し、dataset→datatableに変換→Treeview格納
という流れのアプリなもので、単純にデータ元を変えようと思ったんですが、ちょっとはまった
以下はサンプルソースを修正していて出たトラブル
1.EnumerableRowCollection(Of DataRow) が未定義になる
→System.Data.DataSetExtensionsを参照設定にいれていなかったため
なお、Microsoft.SqlServer.Typesも参照設定にいれないといけません
2.SqlHierarchyIdへのキャストに失敗する
どういうことかというと
//filter the table using linq. See blog for equals()/== issue
EnumerableRowCollection<DataRow> query =
from TNodes in oTable.AsEnumerable()
where TNodes.Field<SqlHierarchyId>
(sKeyField).GetAncestor(1).Equals(iID)
select TNodes
この部分の、
TNodes.Field<SqlHierarchyId>
(sKeyField).GetAncestor(1).Equals(iID)
がSqlHierarchyIdにキャストできないといわれる
よく見ると、xsdファイル…つまりDataSetのDatatypeがStringになっていた
もとはSqlHierarchyIdの型のはずなんだが、.NetのWebサービス上ではStringになるようだ
よく考えたらそりゃそうか。SOAPで、独自の型使うDataSetにはされないってことなんだな
hierarcyid型はSQLServer独自の型だから自動的にStringに変換されるという認識でよいのだろうか
データ取得元のテーブルの状態で、Stringになってるんだから、これを再度hierarcyid型に変換しないといけない
Webサービスからとってきたデータテーブルを
Dim dummyTable As DataTable = dt.Clone()
dummyTable.Columns("testHierarchyid").DataType = GetType(SqlHierarchyId)
という形でクローンテーブルにコピーした後、SqlHierarchyId.Parseを使ってclone側のテーブルにデータを
うつす必要があった
なお、一括でStreamなどに移してコピーしようとしたけど失敗した。やっぱSqlHierarchyId型はいろいろ難しい…
上記を修正したら、とりあえずTreeViewにテーブルの内容は表示されました。
が……これ、追加更新して、SQLServerに戻すのってどうやんの。
世間のサンプルはどれもこれも直接SQLでの書き込み更新ばっかりで、.Net上でTableAdapterとか介してWebサービス経由でデータを送るようなサンプルがない
.Net上からのSQLを書かないSQLServerへのHierarchyID型テーブル書き込みをこれから調べないとorz
どこかに情報ないかなあ