【发布时间】:2016-09-29 22:55:44
【问题描述】:
我正在根据从数据库中获取的安全权限动态构建导航栏。数据库查找包括页面名称。最初我使用数据读取器并执行以下操作:
SqlDataReader SRmenu = sqlCMD.ExecuteReader();
HtmlGenericControl liToAdd;
if (SRmenu.HasRows)
{
while (SRmenu.Read())
{
liToAdd = new HtmlGenericControl("li");
MainUL1.Controls.Add(liToAdd);
HtmlGenericControl addpage = new HtmlGenericControl("a");
addpage.Attributes.Add("href", Convert.ToString(SRmenu["PageName"]));
addpage.InnerText = Convert.ToString(SRmenu["Name"]);
liToAdd.Controls.Add(addpage);
}
}
SRmenu.Close();
conn.Close();
这工作得非常好,直到我想添加可能的下拉菜单(对于该人可以访问的页面超过一页的部分)。我的更新代码如下
if (SRmenu.HasRows)
{
while (SRmenu.Read())
{
LoopCount = LoopCount + 1;
Int32 AppCount = Convert.ToInt32(SRmenu["AppCount"]);
if (AppCount > 1)
{
Int32 ApplicationID = Convert.ToInt32(SRmenu["ApplicationID"]);
Int32 ApplicationID2 = Convert.ToInt32(SRmenu["ApplicationID"]);
liToAdd = new HtmlGenericControl("li");
liToAdd.Attributes.Add("class", "dropdown");
MainUL1.Controls.Add(liToAdd);
HtmlGenericControl addhref = new HtmlGenericControl("a");
addhref.Attributes.Add("href", Convert.ToString(SRmenu["PageName"]));
addhref.InnerText = Convert.ToString(SRmenu["Name"]);
liToAdd.Attributes.Add("class", "dropdown-toggle");
addhref.Attributes.Add("data-toggle", "dropdown");
liToAdd.Controls.Add(addhref);
HtmlGenericControl addspan = new HtmlGenericControl("span");
addspan.Attributes.Add("class", "caret");
addhref.Controls.Add(addspan);
HtmlGenericControl addUL = new HtmlGenericControl("ul");
addUL.Attributes.Add("class", "dropdown-menu");
liToAdd.Controls.Add(addUL);
while (ApplicationID == ApplicationID2)
{
HtmlGenericControl addDropDown = new HtmlGenericControl("li");
addUL.Controls.Add(addDropDown);
HtmlGenericControl addpage = new HtmlGenericControl("a");
addpage.Attributes.Add("href", Convert.ToString(SRmenu["PageName"]));
addpage.InnerText = Convert.ToString(SRmenu["Name"]);
addDropDown.Controls.Add(addpage);
SRmenu.Read();
if (LoopCount < FieldCount)
{ ApplicationID2 = Convert.ToInt32(SRmenu["ApplicationID"]); }
else
{ ApplicationID2 = 0; }
LoopCount = LoopCount + 1;
}
}
else
{
liToAdd = new HtmlGenericControl("li");
MainUL1.Controls.Add(liToAdd);
HtmlGenericControl addpage = new HtmlGenericControl("a");
addpage.Attributes.Add("href", Convert.ToString(SRmenu["PageName"]));
addpage.InnerText = Convert.ToString(SRmenu["Name"]);
liToAdd.Controls.Add(addpage);
}
}
}
我遇到的问题是在 READ() 循环中添加一个循环。目前我正在尝试使用 While (ApplicationID == ApplicationID2) 循环,这让我得到第一个值而不是第二个(目前只有两个页面属于同一个 ApplicationID,它们是我的最后两条记录Read() 循环) - 问题是第二个值永远不会进入下拉列表。
当我在调试中运行它时,它不会经过第二个循环,它会点击“if (SRmenu.HasRows)”它无法找到其他行,因此它存在循环 - 如果我注释掉整个 IF/ELSE并返回到我的原始代码,它确实看到了所有预期的页面,因此数据存在。
我知道如何在经典 ASP 中完成此任务,但我正在努力在 C#/ASP.NET 中找到类似的解决方案。我会在经典中做的是类似于
RSMenu.open
do while not RSMenu.EoF
if PageCount>1 then
<code for drop down segment>
do while count < PageCount
<LI HTML Code>
RSMenu.MoveNext
loop
else
<LI HTML Code>
end if
RSMenu.MoveNext
loop
编辑
- 更新了关于 FOR 循环的评论
- 删除了对 FOR 循环的引用。这不是我正在使用的东西,并且在重新阅读后觉得它与我的问题无关。它被列为另一种考虑的方法,但似乎无法解决上述问题。
- 看起来像 NextResult();是错误的命令,它循环了一批命令,它不会迭代到该读取集中的下一条记录 - 所以我想弄清楚的是如何做到这一点。
- 显然 Read() 迭代到下一条记录。 'HasRows' 方法不能用于测试它是否仍然有行,所以我在循环之前添加了一个 FieldCount,并在其中添加了一个 LoopCount。这很有效。
【问题讨论】:
-
你最后的“for”循环确实从行中获取每个值(reader.GetValue(i) 获取当前行的第 i 列的值)。
-
@David_001 - 抱歉,我的意思是说它不允许我遍历行。会更新。
-
@David_001 我曾提到 FOR 循环是我考虑过的另一种解决方案,但它的功能似乎与我所做的不同。阅读我的帖子后,我觉得这是不相关的辅助信息(因为我目前没有使用它,也没有尝试/考虑过其他方法)。
-
我发现了一点我的问题,NextResult();命令不会遍历当前的 READ(),如果您正在执行一批记录,它会转到下一个数据集。所以我的核心问题是如何在不回到循环顶部的情况下迭代读取记录。或者我可以重做我的 HTML 方法以将它们部分移出循环。
-
与您的问题无关 - 但通常值得拥有基于 POC 的强类型数据模型,而不是直接从 db 获取值到控制树。缓存也很方便(您不需要为每个请求查询 db 导航)。
标签: c# asp.net datareader