- PR -

ASP.NETで階層メニューをつくるには

投稿者投稿内容
Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2004-09-27 22:39
 DBがOracleなら、階層取得ができますが、SQL Serverにはそのようなコマンドがないのでできません。

 自分の環境は明記しましょう。そのほうが回答が早いですよ。
KIN
会議室デビュー日: 2004/09/27
投稿数: 5
投稿日時: 2004-09-28 09:29
jittaさん、返答ありがとうございます。
    引用:
    -----------------------------------------------------------------------
     DBがOracleなら、階層取得ができますが、SQL Serverにはそのようなコマンドが
    ないのでできません。
    -----------------------------------------------------------------------

DBはSQL Serverを使用しています。
SQL Serverでは簡単に取得ができないということでしょうか?
簡単な方法以外でも構いませんので、ご教授お願い致します。

[ メッセージ編集済み 編集者: KIN 編集日時 2004-09-28 09:30 ]
Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2004-09-28 21:06
 私の投稿欄のしたにある「www」というリンクをクリック。
 「.NET FrameworkおよびVS.NETに関するTips」の、上から3つめに「階層問い合わせの類似」があります。
転記(斜字体は、環境に合わせて書き換えること。その他にも、書き換えが必要な箇所あり)
コード:
Dim dset As New System.Data.DataSet("HierarchicalDataSet")
Dim tbl As New System.Data.DataTable("HierarchicalTable")
Dim adpt As System.Data.DbDataAdapter = New アダプタ

' 階層構造を作る
adpt.SelectCommand.CommandText("SELECT * FROM HIERARCHICALTABLE")
adpt.Fill(dset, tbl)
' 外部制約を追加する
dset.Relations.Add("SelfReference", tbl.Columns("ID"), tbl.Columns("FK_PARENT"))

' 使う
Dim cnt As Integer
Dim rows() As System.Data.DataRow
Dim row As System.Data.DataRow
Dim queue As New System.Collections.Queue
rows = tbl.Select(階層のトップを問い合わせる条件)
For cnt = 0 To rows.Length - 1
	queue.Enqueue(rows(cnt))
Next
While Not (queue.Peek() Is Nothing)
	row = queue.Dequeue
	取り出した行の操作
	rows = row.GetChildRows("SelfReference")
	For cnt = 0 To rows.Length - 1
		queue.Enqueue(rows(cnt))
	Next
End While



ここで注意するのは、「外部制約をDbDataAdapter.Fillより前に追加してはいけない」ということ。そうすると、Fillメソッドが制約違反で失敗します。あ、なんか、他のスレッドに関係するような???もちろん、テーブルをクリアするときには、先に制約を削除します。

 最後のwhileループは、「子があるデータ」をキューに格納することによって、再帰呼び出しをせずにデータを処理しています。「取り出した行の操作」のところで、階層型のクラスに代入していけばよいでしょう。その階層型クラスをASP.NETのカスタムコンポーネントとして作り、RenderメソッドでHTMLを作成するようにすれば一丁上がりです。
KIN
会議室デビュー日: 2004/09/27
投稿数: 5
投稿日時: 2004-09-29 19:06
jittaさん、ご返答ありがとうございます。
jittaさんのコードをコピペし、斜字体になっているところを
わかる範囲で書き換えたのですが、コンパイルエラーが出ました。
下記のコードでコンパイルエラーが発生しました。
>adpt.SelectCommand.CommandText("SELECT * FROM HIERARCHICALTABLE")
>adpt.Fill(dset, tbl)
adptはSQLServerなのでsqldataadapterに書き換えましたが、
そこが原因でしょうか?

>adpt.SelectCommand.CommandText("SELECT * FROM HIERARCHICALTABLE")
上記のコードでは「プロパティアクセスはプロパティに割り当てるか、
またはその値を使わなければなりません。」と出ています

>adpt.Fill(dset, tbl)
上記のコードは「型’System.Data.DataTable’の値を'String'に変換できません。」
と出ています。

できればもう少しやさしいサンプルなどがあるとうれしいです。
platini
大ベテラン
会議室デビュー日: 2002/12/03
投稿数: 193
投稿日時: 2004-09-29 19:39
引用:

>adpt.Fill(dset, tbl)
上記のコードは「型’System.Data.DataTable’の値を'String'に変換できません。」
と出ています。

できればもう少しやさしいサンプルなどがあるとうれしいです。


エラーメッセージが怒っているそのままです。
Stringを要求されているのです。
DbDataAdapter.Fill のヘルプを見て、
1番目の引数にDatasetを取り、2つ目の引数に○型を取るパターンを引けば自明です。

>できればもう少しやさしいサンプルなどがあるとうれしいです。
がんばってください。
Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2004-09-29 22:26
String型でしたね。テーブル名を入れましょう。

というか、ここも書き換えなければならないところですね。というより、第1引数だけでもいいかも。

 で、DataTableのテーブル名と、SELECT文で持ってくるテーブル名は、一致させておく必要があります。

 確かに、難しいかも。。。

難しいかも、だけど、使うところはもっと難しいので、これくらいでへこたれないでください^o^;

[ メッセージ編集済み 編集者: Jitta 編集日時 2004-09-29 22:30 ]
Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2004-10-01 21:35
 別のところでも話題になっていたので、コントロールを作ってみました。

 下の「www」のリンクから私のウェブページへいって、「ASP.NET でのプログラミングに関するTips」のページの、今のところ一番下。

 使い方は、かなり難しいかも。。。

スキルアップ/キャリアアップ(JOB@IT)