У меня плоский список записей из хранимой процедуры 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;
}