Иерархическое управление базами данных в MVC - PullRequest
1 голос
/ 28 апреля 2009

Я использую приведенный ниже код в качестве 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 ]

1 голос
/ 15 июня 2009

См. здесь для ответа

1 голос
/ 28 апреля 2009

Я бы сделал здесь две вещи: не пытайтесь сделать это самостоятельно: используйте jQuery. Если вы пользуетесь Google «jquery menu», вы найдете сотни ссылок.

Далее, поместите логику упорядочения в ваше приложение, вам не нужна БД для этого, поскольку она впитывает циклы и (из того, что я прочитал) не очень эффективна. Это простая циклическая логика с самообращающейся связью, для которой идеально подходит Linq.

Передайте это jQuery, и вы хорошо обходитесь без жесткого кодирования HTML в коде:)

0 голосов
/ 23 июня 2009

Я всегда использую рекурсивные табличные функции для извлечения иерархических данных на SQL-сервере.

Смотрите пример здесь: blogs.conchango.com/christianwade/archive/2004/11/09/234.aspx

К сожалению, существует рекурсивное ограничение (максимум 32 уровня) для пользовательских функций SQL Server и хранимых процедур.

Примечание. Если вы используете табличную функцию, просто поместите ее в файл dbml, и вы сможете получить к ней доступ, как и к любой другой таблице.

Другой подход заключается в использовании нового синтаксиса рекурсивных запросов (в форме предложения WITH и Common Table Expressions-CTE), введенного в SQL Server 2005.

Посмотрите здесь: 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

0 голосов
/ 28 апреля 2009

Если вы используете Sql server 2005, обратите внимание на Common Table Expression (CTE) (Google с иерархическими данными CTE) Позволяет создать представление, отображающее полную иерархию.

Но какой уровень глубины вы отображаете в меню? Обычно вам нужно только показать непосредственные дочерние элементы и перейти в иерархию, когда пользователь нажимает на ссылки. (Рекурсия не требуется)

...