- Kimi
- 会議室デビュー日: 2008/10/03
- 投稿数: 7
|
投稿日時: 2008-10-05 15:00
何度も申し訳ありません。
昨晩、テストデータ(下記の小ねじデータのみ)で出来たつもりでしたが、テストデータを下記のように「大ネジ」データを増やしてやったところ、次のような流れで処理が終わってしまいました。
【処理の流れを追ってみました(○数字は下記のソースの番号です)】
@parent:"-" →「部品名1」を読込み
@parent:"nameA.aspx" →「小ねじ」を読込み
@parent:"nameB.aspx" →「5mm*10mm」を読込み
@parent:"n1.aspx" →「5mm*15mm」を読込み
B →"n1.aspx"レコードはparentにありません
D
A「5mm*10mm」をTreeViewに書き込み、再帰から戻ってきた
A「小ねじ」をTreeViewに書き込み、再帰から戻ってきた
A「部品名1」をTreeViewに書き込み、再帰から戻ってきた
C次のレコードを読もうとして、次のエラーメッセージが表示されました
『データリーダが閉じているときに、無効な操作Readをしようとしました』
D
これで処理が終了して、
■部品名1
└小ねじ
└5mm*10mm
この形でTreeViewが作成されました。
【テストデータ】
url |title |parent
------------+----------+-------
default.aspx|部品名1 |-
nameA.aspx |小ねじ |Default.aspx
ne1.aspx |5mm*10mm |nameA.aspx
ne2.aspx |5mm*15mm |nameA.aspx
nameB.aspx |大ねじ |Default.aspx
ne3.aspx |10mm*100mm|nameB.aspx
:
:
【本来期待したい形】
■部品名1
├小ねじ
|├5mm*10mm
|└5mm*15mm
├大ねじ
|├10mm*100mm
:
:
【実行したソースです】
Protected Sub Page_Init(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Init
If IsPostBack = False Then
Me.CreateNode("-", tree.Nodes)
End If
End Sub
@ Private Sub CreateNode(ByVal pParent As String, ByVal nodes As TreeNodeCollection)
COMM = "SELECT * FROM t_zaiko WHERE parent = '" & pParent & "'"
Using connect As New SqlConnection(dbConnectString)
Dim SQLcom As New SqlCommand(COMM, connect)
Try
connect.Open()
COMMr = SQLcom.ExecuteReader
While COMMr.Read = True
Dim node As New TreeNode()
node.NavigateUrl = COMMr("url")
node.Text = COMMr("title")
node.Value = COMMr("url")
CreateNode(COMMr("url"), node.ChildNodes)
A:再帰から戻ってきた
nodes.Add(node)
End While
B:レコードなし
Catch ex As Exception
C:エラー
End Try
End Using
D
End Sub
最後に再帰から戻ってきて、次のレコードを読もうとした時に、一番最初のデータリーダが閉じられてしまっているようです。
クローズしていないので何故クローズ状態になるのでしょうか?
また、小ノードを追加するために再帰的に実行していますが、再帰した時は@から実行されるようですので、同じデータリーダが存在することになると思います(違いますか?)。
これは大丈夫なのでしょうか?
どなたか、ご教授して頂ける方がおられましたら、よろしくお願い致します。
|
- ぴあちゃん
- ぬし
- 会議室デビュー日: 2008/02/07
- 投稿数: 287
|
投稿日時: 2008-10-06 19:17
ステップ実行してどこでエラーが出ているのか確認して下さい。
エラーメッセージはそのまんま、
「データリーダが閉じているときに、無効な操作Readをしようとしました」
です。
これをどこかでやっています。たぶん。
Java で悪いのですが、VB.NET に毛が生えたようなイメージで捉えて
もらえるとうれしいですねw
再帰処理部分は応用できるでしょう。
処理結果
■在庫管理■
■ネジ
▼10mm
▼15mm
▼20mm
■逆ネジ
▼10mm
▼15mm
▼20mm
■ナット
■ワッシャ
■リベット
データベースに登録してあるデータ(XML 形式)
コード: |
|
<?xml version="1.0" encoding="Shift_JIS" ?>
<db name="ZAIKOTBL">
<node name="■ネジ" id="0" pid="" />
<node name="▼10mm" id="1" pid="0" />
<node name="▼15mm" id="2" pid="0" />
<node name="▼20mm" id="3" pid="0" />
<node name="■逆ネジ" id="4" pid="0" />
<node name="▼10mm" id="5" pid="4" />
<node name="▼15mm" id="6" pid="4" />
<node name="▼20mm" id="7" pid="4" />
<node name="■ナット" id="8" pid="" />
<node name="■ワッシャ" id="9" pid="" />
<node name="■リベット" id="10" pid="" />
</db>
|
DataSet のエミュレータ?
コード: |
|
/*
* 作成日: 2008/10/06
*/
package jp.co.test;
import org.xml.sax.*;
import javax.xml.parsers.*;
import java.io.*;
import java.util.*;
import org.xml.sax.helpers.DefaultHandler;
public class MyDataSet extends DefaultHandler {
Map map = new HashMap();
private String currentDbName;
MyDataRowCollection mrc;
public MyDataSet(String xmlFile) throws IOException, SAXException, ParserConfigurationException {
SAXParserFactory sax = SAXParserFactory.newInstance();
SAXParser parser = sax.newSAXParser();
parser.parse(new File(xmlFile), this);
}
public void startElement(String url, String localName, String qName, Attributes attr) {
if (qName.equals("db")) {
currentDbName = attr.getValue("name");
mrc = new MyDataRowCollection();
map.put(currentDbName, mrc);
}
if (qName.equals("node")) {
mrc.addRow(new MyDataRow(
attr.getValue("name"),
attr.getValue("id"),
attr.getValue("pid")));
}
}
public MyDataRowCollection getDataSet(String dbName) {
return (MyDataRowCollection)map.get(dbName);
}
public static void main(String[] args) {
try {
MyDataSet m = new MyDataSet("TEST.xml");
MyDataRowCollection mrc = m.getDataSet("ZAIKOTBL");
Iterator it = mrc.listIterator();
while (it.hasNext()) {
MyDataRow mr = (MyDataRow)it.next();
System.out.println(mr);
}
}
catch (Exception we) {
we.printStackTrace();
}
}
}
|
DataRowCollection のエミュレータ?
コード: |
|
/*
*/
package jp.co.test;
import java.util.*;
/**
*/
public class MyDataRowCollection {
List list = new ArrayList();
public void addRow(MyDataRow row) {
list.add(row);
}
public MyDataRow getRow(int index) {
return (MyDataRow)list.get(index);
}
public MyDataRow[] getPids(String pid) { //same pid コレクション
List ls = new ArrayList();
for (int i=0;i < list.size();i++) {
MyDataRow r = getRow(i);
if (r.getPid().equals(pid)) ls.add(r);
}
return (MyDataRow[])ls.toArray(new MyDataRow[ls.size()]);
}
public Iterator listIterator() {
return list.iterator();
}
}
|
DataRow のエミュレータ?(かなり違うかも)
コード: |
|
/*
* 作成日: 2008/10/06
*/
package jp.co.test;
/**
*/
public class MyDataRow {
private String id;
private String pid;
private String name;
public MyDataRow(String name, String id, String pid) {
setId(id);
setPid(pid);
setName(name);
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPid() {
return pid;
}
public void setPid(String pid) {
this.pid = pid;
}
public String toString() {
StringBuffer sb = new StringBuffer();
sb.append("<node name='").append(name).append("' id='");
sb.append(id).append("' pid='").append(pid).append("' />");
return sb.toString();
}
}
|
TreeView クラスのエミュレータ
コード: |
|
/*
* 作成日: 2008/10/06
*/
package jp.co.test;
import java.util.*;
public class TreeView {
public class TreeNode {
String name;
List childNodes = new ArrayList(); //of TreeNode
public String getName() {
return this.name;
}
public TreeNode(String name) {
this.name = name;
}
public void add(TreeNode node) {
childNodes.add(node);
}
public boolean hasChild() {
return childNodes.size() > 0;
}
public int count() {
return childNodes.size();
}
public Iterator listIterator() {
return childNodes.iterator();
}
}
public static void main(String[] args) {
TreeView tv = new TreeView();
TreeNode root = tv.new TreeNode("■在庫管理■");
tv.createTree(root, "");
tv.showTreeView(root, 0);
}
public void createTree(TreeNode root, String pid) {
try {
MyDataSet m = new MyDataSet("TEST.xml");
MyDataRowCollection mrc = m.getDataSet("ZAIKOTBL");
MyDataRow[] rows = mrc.getPids(pid);
for (int i=0;i < rows.length;i++) {
MyDataRow row = rows[i];
TreeNode node = new TreeNode(row.getName());
createTree(node, row.getId());
root.add(node);
}
}
catch (Exception we) {
we.printStackTrace();
}
}
public void showTreeView(TreeNode root, int indent) {
Iterator it = root.listIterator();
showTreeNode(root, indent++);
while (it.hasNext()) {
TreeNode tr = (TreeNode)it.next();
showTreeView(tr, indent);
}
}
public void showTreeNode(TreeNode node, int indent) {
indent = indent * 2;
String indents = " ";
System.out.println(
indents.substring(indents.length() - indent) +
node.getName()
);
}
}
|
とりあえず、3つくらい前のレスで載せた手順通りに組みまして
正常に動作することは確認できました。
ですので、後はあなたの書き方に問題があるとしか言えません。
たぶん、前に開いたコネクションが勝手に閉じられてしまうという
のはDBのコネクション数が絡んでくる話かと思います。
通常コネクションは1つらしいのでこれを増やすか、データセット
取得したらとりあえずコネクションを閉じる、とか工夫したら
いけるんじゃないかと想像しています。
※しかしなんで TreeNodeCollection なんて使うんです?
じゃんぬねっとさんが言っているように、TreeNode は自身に
子供のコレクションを持っているのでこいつをそのまんま渡せば
済むと思うんだけど。
Javaでごめんなさい、でもやってることは同じです。
# getDataSet ってやっといて返すのはコレクション、なんじゃそりゃ
# な意味不明なメソッドですね。頭こんがらがっています;;
[ メッセージ編集済み 編集者: ぴあちゃん 編集日時 2008-10-06 19:27 ]
|