0

データベースとしてSQLServer2008 R2を使用して、asp.netでデータ駆動型の動的メニューを作成しています。親ノードと、最初のレベルの子ノードは問題なく機能します。ただし、子ノードが別の子ノードの下にある場合、アプリケーションは例外を生成します。私の問題のC#コードは次のとおりです:

public partial class LeaveManagementSystemMasterPage : System.Web.UI.MasterPage
{
SqlConnection conn;
protected void Page_Load(object sender, EventArgs e)
{
    if (!IsPostBack)
    {
        getMenu();
    }
}

private void getMenu()
{
    Connect();
    conn.Open();
    DataSet ds = new DataSet();
    DataTable dt = new DataTable();
    string sqlQuery = "select * from menu";
    SqlDataAdapter da = new SqlDataAdapter(sqlQuery, conn);
    da.Fill(ds);
    dt = ds.Tables[0];
    DataRow[] rowParent = dt.Select("ParentID=" + 0);
    DataRow[] rowChild = dt.Select("ParentID>"+0);

    //populating the first level of the menu
    foreach (DataRow dr in rowParent)
    {
        Menu1.Items.Add(new MenuItem(dr["MenuName"].ToString(),dr["MenuID"].ToString(),"",""));
    }

    //populating the children in menu
    foreach (DataRow dr in rowChild)
    {
        MenuItem child = new MenuItem(dr["MenuName"].ToString(), dr["MenuID"].ToString(), "", "");
        Menu1.FindItem(dr["ParentID"].ToString()).ChildItems.Add(child);

    }


    conn.Close();

}

public void Connect()
{
    string conStr="Data Source=HO-0000-LAP; Initial Catalog=LeaveManagementSystem; Integrated Security=true";
     conn = new SqlConnection(conStr);
}

}

そしてこれが私がsqlserver2008で設計した私のテーブルです:-

メニューデータベース

4

2 に答える 2

1

この問題に役立つ解決策は、次の場所で見つかりました

asp.net のデータベースからメニュー項目を取得する

そして、ここに私のソースコードがあります:-

public partial class LeaveManagementSystemMasterPage : System.Web.UI.MasterPage

{ SqlConnection conn; protected void Page_Load(object sender, EventArgs e) { if (!IsPostBack) { getMenu(); } }

private void getMenu()
{
    Connect();
    DataSet ds = new DataSet();
    DataTable dt = new DataTable();
    string sqlQuery = "select * from menu";
    SqlDataAdapter da = new SqlDataAdapter(sqlQuery, conn);
    da.Fill(ds);
    dt = ds.Tables[0];
    AddTopMenuItems(dt);


}

private void AddTopMenuItems(DataTable menuData)
{
    DataView view = new DataView(menuData);
    view.RowFilter = "ParentID = 0";
    foreach (DataRowView rowView in view)
    {
        MenuItem topItem = new MenuItem(rowView["MenuName"].ToString(),rowView["MenuID"].ToString());
        Menu1.Items.Add(topItem);
        AddChildItems(menuData, topItem);
    }

}

private void AddChildItems(DataTable menuData, MenuItem parentMenuItem)
{
    DataView view = new DataView(menuData);
    view.RowFilter = "ParentID = " + parentMenuItem.Value;

    foreach(DataRowView rowView in view)
    {
        MenuItem childItem = new MenuItem(rowView["MenuName"].ToString(), rowView["MenuID"].ToString());
        parentMenuItem.ChildItems.Add(childItem);
        AddChildItems(menuData, childItem);
    }

}

public void Connect()
{
    string conStr="Data Source=HO-0000-LAP; Initial Catalog=LeaveManagementSystem; Integrated Security=true";
     conn = new SqlConnection(conStr);
}

}

于 2013-03-07T11:37:44.340 に答える
0

ここで推測してみると、それは第 3 レベルの子アイテムの作成順序に関係していると言います。

rowParent コレクションから明示的に親項目をメニューに追加してから、「残り」を追加します。問題は、子を追加するために 2 番目の for ループを開始するときに、より高いレベルのアイテムが最初に追加されるようなアイテムの順序に依存していることです。これは保証されません。

したがって、何が起こっている可能性がありますか(例外を投稿した場合、確認できます)は次のようになります

foreach ループ (rowParent 上) の後、メニュー オブジェクトに 5 つの親項目がすべて追加されます。

Administration (ID 1), 
Setup (ID 2)
Operations (ID 3) 
Reports (ID 4) 
Logout (ID 5)

たとえば、2 番目の foreach では、たとえば、これが問題の原因である可能性が高いため、2 つのアイテムがある日を許可します。

Management ID 31, ParentID 3
Initiate Application ID 311, ParentID 31

Management が最初に追加された場合、FindItem() が追加先の親を見つけるため、Initiate Application が機能します。

ただし、開始アプリケーションが最初に実行され、管理がまだ追加されていない場合は、FindItem() が失敗する (アイテムがまだ追加されていない) ため、エラーがスローされます。

order by 句と order by Parent ID を追加して、番号の小さい親アイテムが最初に追加されるような順序でアイテムが追加されるようにすることができます。

または、関数を作成して、レベルごとに親 ID を数回渡すことで、既に追加されている親に子アイテムを常に追加していることを確認できます。今は iPad ですが、すぐにコードを追加します。

于 2013-03-07T11:23:50.630 に答える