Как отобразить ненормализованные данные в иерархической структуре? - PullRequest
1 голос
/ 06 мая 2010

Моя проблема в том, что я хочу отображать данные в иерархической структуре следующим образом:

  • демократ
    • Секретарь округа
      • Кандидат 1
      • Кандидат 2
    • Магистрат
      • Кандидат 1
      • Кандидат 2
      • Кандидат 3

Но я получаю набор данных следующим образом:

Party | Office | Candidate
--------------------------------------------
Democrat | County Clerk | Candidate 1
Democrat | County Clerk | Candidate 2
Democrat | Magistrate | Candidate 1
Democrat | Magistrate | Candidate 2
Democrat | Magistrate | Candidate 3

Я планировал использовать вложенные повторители, но для этого мне нужно отдельное значение Party, а затем разные значения названия офиса в этой партии.

Существуют ли какие-либо функции .NET, позволяющие легко делать то, что я пытаюсь сделать? Будет ли лучший способ отображения информации, кроме повторителей?

Заранее спасибо!

Ответы [ 3 ]

2 голосов
/ 29 мая 2010

Если вы можете изменить хранимую процедуру, я бы рекомендовал набор результатов в виде списка смежности:

ID    Name          ParentID
1     Democrat      NULL
2     County Clerk  1
3     Magistrate    1
4     Candidate 1   2
5     Candidate 2   2
6     Candidate 1   3
7     Candidate 2   3
8     Candidate 3   3

Сокращает объем извлекаемых данных и позволяет рекурсивно программировать отношения родитель-потомок. Вы просто начинаете с корня. Этот подход позволяет избежать хлопот, связанных с использованием вложенных повторителей, путем непосредственного построения строкового литерала в StringBuilder.

StringBuilder sb = new StringBuilder();
DataTable dt = new DataTable();
someDataAdapter.Fill(dt);

// find the roots:
DataRow[] roots = dt.Select("parentId is null");

sb.Append("<ul>");
foreach (DataRow child in roots)
{
    WriteNode(child, sb);
}
sb.Append("</ul>");


// recursively write out each node
public static void WriteNode(DataRow row, StringBuilder sb) {
    sb.Append("<li>"); 
    sb.Append(row["Name"]);

    // find children rows...
    DataRow[] children = row.Table.Select("parentId = " + row["id"].ToString());
        if (children.Length > 0)
        {
            sb.Append("<ul>");
            foreach (DataRow child in children)
            {
                WriteNode(child, sb);
            }
            sb.Append("</ul>");
        }

        sb.Append("</li>");
    }
1 голос
/ 29 мая 2010

Я не уверен, что вас заинтересует использование стороннего элемента управления, но у меня было ТОЧНО ТО ЖЕ требование, которое требовалось отображать данные иерархически, отображая повторяющиеся значения как единое целое со сворачиваемыми узлами (например, деревьями). Однако элементы управления Tree не привязаны к данным и все еще нуждаются в достаточном количестве кода. Но этот стиль построения дерева на основе ненормализованных данных может быть легко реализован с помощью DataBinding. Я использовал FlexGrid для привязки DataBable к DataTable, и ему просто нужно было несколько строк кода, чтобы ТОЧНО отобразить то, что вам нужно, хотя и на основе стороннего элемента управления.

Я использовал элемент управления ComponentOne FlexGrid и использовал его функцию «SubTotal» для генерации иерархических данных. Я вставляю приведенный ниже код на всякий случай, если вы заинтересованы в использовании ComponentOne FlexGrid. Вы можете скачать демонстрационную копию и проверить.

        // Showing master policy in GROUPS
        // -----------------------------------------------------------------------------------
        // set tree mode to show settings in GROUPS
        flxAvailableSettings.Tree.Style = TreeStyleFlags.Simple;
        // show outline tree on column 1.
        flxAvailableSettings.Tree.Column = 0;
        flxAvailableSettings.Cols[0].Visible = true;
        flxAvailableSettings.Cols[0].Width = 15;
        flxAvailableSettings.AllowMerging = AllowMergingEnum.Nodes;
        // subtotal on column 1, outline level 0
        flxAvailableSettings.Subtotal(AggregateEnum.None, 0, 0, 0, "{0}");
        // use owner draw to suppress repeating group names in Non-Node rows
        flxAvailableSettings.DrawMode = DrawModeEnum.OwnerDraw;
        flxAvailableSettings.OwnerDrawCell += new C1.Win.C1FlexGrid.OwnerDrawCellEventHandler(flxAvailableSettings_OwnerDrawCell);
        // done, autosize columns to finish
        flxAvailableSettings.AutoSizeCols();
        // -----------------------------------------------------------------------------------

    private void flxAvailableSettings_OwnerDrawCell(object sender, C1.Win.C1FlexGrid.OwnerDrawCellEventArgs e)
    {
        if (!flxAvailableSettings.Rows[e.Row].IsNode && flxAvailableSettings.Cols[e.Col].Name == "PolicyGroup")
            e.Text = "";
    }

Строка flxAvailableSettings.Subtotal (AggregateEnum.None, 0, 0, 0, "{0}") генерирует группы деревьев, хотя мне нужно было группировать по одному столбцу, вы можете использовать группы по нескольким столбцам. Просто обратитесь к их документам на Subtotalling.

Надеюсь, это поможет.

0 голосов
/ 29 мая 2010

Элемент управления TreeView даст вам нужный формат. Однако заполнение его из базы данных требует определенных усилий. Здесь есть статья о заполнении asp.net TreeViews из базы данных: http://www.codeproject.com/KB/tree/TreeViewWithDatabase.aspx

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...