MVC中的分层数据库驱动菜单

时间:2009-04-28 16:27:04

标签: sql-server asp.net-mvc linq subsonic

我使用下面的代码作为HTMLHelper,它从数据库中获取数据并在其上循环以显示菜单。这是相当简单的,但是你可以看到,如果你有一个数据库表使用相邻的层次结构模型,例如/ ID,ParentID,OrderID,该怎么办?很容易看到发生了什么,但需要递归才能正确地获取这些数据。编写C#递归函数是否可以接受?如果是这样,有人能帮助我吗?预期的输出与此类似。

<ul>
  <li>Item1
    <ul>
      <li>SubItem1</li>
    </ul>
  </li>
</ul>

SQL 2008现在有一个Hierarchy数据类型,所以我不确定这是否有用?

我还想要一些方法让用户能够决定菜单中的内容,例如可以进入菜单的项目列表,然后选择这些项目及其在层次结构中的位置。按下保存的按钮后,它会将此层次结构存储在数据库中。

我问得太多了,我确定这一定是一个非常常见的情况吗?

这是我的HTMLHelper代码,如果有人想要使用它......

 public static string Menu(this HtmlHelper helper, int MenuCat)
{

    string menuHTML = "<ul id=\"menu\">";

    var route = helper.ViewContext.RequestContext.RouteData;
    string currentPageName = route.GetRequiredString("id");

    DB db = DB.CreateDB();

    //var result = from p in db.WebPages where p.CategoryID == 9 select p;
    var result = from p in db.WebPages select p;

    foreach (var item in result)
    {
        if (item.Name == currentPageName)
        {

            menuHTML += "\n\t<li>" + helper.ActionLink(item.Name, "Details", "Dinner", new { id = item.ID }, new { @class = "selected" }) + "</li>";
        }
        else
        {
            menuHTML += "\n\t<li>" + helper.ActionLink(item.Name, "Details", "Dinner", new { id = item.ID }, null) + "</li>";
        }
    }

    menuHTML += "\n</ul>\n";

    return menuHTML;


}

4 个答案:

答案 0 :(得分:1)

我会在这里做两件事:不要费心自己渲染:使用jQuery。如果您使用谷歌“jquery菜单”,您将找到数百个链接。

接下来,将订购逻辑放在您的应用程序上,您不需要DB来执行此操作,因为它会吸收周期并且(从我读过的内容)并不是非常有效。这是一个简单的循环逻辑,具有Linq非常适合的自引用连接。

把它交给jQuery,如果你没有在代码中硬编码HTML,那么你很高兴。)

答案 1 :(得分:1)

请参阅here了解答案

答案 2 :(得分:0)

如果您使用的是Sql server 2005,请查看Common Table Expression(CTE)(谷歌与CTE分层数据)。它允许您创建显示完整层次结构的视图。

但是,您在菜单中显示的深度级别是多少?通常,您只需要显示直接的孩子,并在用户单击链接时进入层次结构。 (不需要递归)

答案 3 :(得分:0)

我总是使用递归表值函数来获取SQL服务器中的分层数据。

在此处查看示例: blogs.conchango.com/christianwade/archive/2004/11/09/234.aspx

不幸的是,SQL Server用户定义函数(UDF)和存储过程存在递归限制(最多32个级别)。

注意:如果使用表值函数,只需将其放在dbml文件中,就可以像访问任何其他表一样访问它。

另一种方法是使用SQL Server 2005中引入的新的递归查询语法(以WITH子句和公用表表达式-CTE的形式)。

看看这里: www.eggheadcafe.com/articles/sql_server_recursion_with_clause.asp

这里介绍了将CTE与Linq-To-SQL混合的方法: stackoverflow.com/questions/584841/common-table-expression-cte-in-linq-to-sql