Словарь <string, object> готовится с использованием плоского списка с родительской дочерней иерархией - PullRequest
0 голосов
/ 12 ноября 2018

У меня плоский список записей из хранимой процедуры SQL, в котором есть столбцы ID, Key, Value, ParentId.

Ключ может иметь любое количество элементов дочернего уровня, или ключ может иметь прямое строковое значение (например, меню). Поэтому я определил свой словарь как ключ и объект (объект может быть строкой или снова Dictionary<string, object>).

Мне нужно подготовить словарь объектов, потому что значения ключей являются динамическими из базы данных, и мне нужно преобразовать его в json. Так что IEnumerable<objects> невозможно. Поэтому я использую Dictionary<string, object>.

Проблема в том, что у него n уровней иерархии. Поэтому при каждом рекурсивном вызове мне может понадобиться что-то вроде yield и return, как мы делаем в случае Enumerable, но в этом словаре мне нужно добавить дочерние уровни к его непосредственному родительскому ключу. Я не уверен, как справиться с этим с помощью словарей.

Вот мой код. Я думаю, что-то упустил.

private Dictionary<string, object> headerFooterValues;
private List<S_Get_HeaderFooter_Result> headerFooterResult = default(List<S_Get_HeaderFooter_Result>);

public bool PrepareTree(List<S_Get_HeaderFooter_Result> headerFooters, Dictionary<string, object> childItems, string parentKey = null)
{
    bool status = false;
    Dictionary<string, object> childKeyValuePairs = new Dictionary<string, object>();
    try
    {
        foreach (S_Get_HeaderFooter_Result item in headerFooters)
        {
            /// always check the whole list
            bool hasChildren = headerFooterResult.Any(row => item.EntityTypeId == row.ParentId);

            /// has children object collection
            if (hasChildren)
            {
                if (!string.IsNullOrEmpty(parentKey))
                {
                    childKeyValuePairs = (Dictionary<string, object>)headerFooterValues[parentKey];
                    childKeyValuePairs.Add(item.Key, new Dictionary<string, object>());
                    headerFooterValues[parentKey] = childKeyValuePairs;
                }
                else
                {
                    headerFooterValues.Add(item.Key, new Dictionary<string, object>());
                }
                status = PrepareTree(headerFooterResult.Where(row => item.EntityTypeId == row.ParentId).ToList(), childKeyValuePairs, item.Key);
            }
            /// has no children
            if (!string.IsNullOrEmpty(parentKey)) //if parent key exists prepare child dictionary items
            {
                childKeyValuePairs = (Dictionary<string, object>)headerFooterValues[parentKey];
                childKeyValuePairs.Add(item.Key, item.Value);
            }
            else if (!headerFooterValues.ContainsKey(item.Key)) //else prepare parentroot dictionary items
            {
                headerFooterValues.Add(item.Key, item.Value);
            }
        }
        if (!string.IsNullOrEmpty(parentKey))
        {
            headerFooterValues[parentKey] = childKeyValuePairs;
        }
        status = true;
    }
    catch (Exception)
    {
        status = false;
        throw;
    }

    return status;
}
...