Можно эмулировать любую другую структуру данных с hashmap, таким образом, это не ужасное ограничение. Сканируя от вершины до нижней части, Вы создаете hashmap для каждой строки базы данных с записью для каждого столбца. Добавьте каждый из этих hashmaps к "основному" hashmap, включил идентификатор. Если какой-либо узел имеет "родителя", которого Вы еще не видели, создаете запись заполнителя для него в основном hashmap и заполняете его, когда Вы видите фактический узел.
Для распечатывания его сделайте простую передачу в глубину через данные, отслеживание уровня отступа по пути. Можно сделать это легче путем хранения "дочерней" записи для каждой строки и заполнения ее, поскольку Вы сканируете данные.
Что касается того, существует ли "лучший" способ сохранить дерево в базе данных, которая зависит от того, как Вы собираетесь использовать данные. Я видел системы, которые имели известную максимальную глубину, которая использовала различную таблицу для каждого уровня в иерархии. Это имеет много смысла, если уровни в дереве не довольно эквивалентны, в конце концов (высокоуровневые категории, являющиеся отличающимся, чем листы).
Вам необходимо вставить
stream.Seek(0, SeekOrigin.Begin);
после вызова
Image.Save()
. Это перемотает поток в начало сохраненного изображения. В противном случае поток будет помещен в конец потока и получателю ничего не будет отправлено.
Попробуйте перемотать поток памяти. «Курсор» остается в конце файла, и читать нечего, пока вы не «перемотаете» поток в начало.
image.Save( stream, ImageFormat.Jpeg );
stream.Seek( 0, SeekOrigin.Begin );
return new FileStreamResult( stream, "image/jpeg" );