ООП: Правильно ли архитектурно так делать?
Возможно, это нормально, так и должно быть ? или как архитектурно правильно решать подобное?
Это нормально. Безликие массивы становятся осмысленными сущностями. Такой код становится проще понимать и поддерживать. 

Используемый вами подход называется data transfer object (DTO). Широко распространенная практика. DTO отлично сочетается с иммутабельностью, которая присутствует в ваших классах.

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

В результате, на каком-то уровне приложения, происходит выборка, а дальше создаются все необходимые объекты, и внедряются друг в друга. (кстати, как называется этот слой приложения, и в чьей зоне ответственности эта задача ?)
Называется ORM. Находится в ответственности ORM слоя/фреймворка.
Оборачивать массивы какой нибудь выборки в объекты для передачи куда нибудь в другой слой или сериализации и передачи по сети это совершенно нормально, ничего в этом такого нет. Скажу даже больше, это оборачивание в "обьект" даже называние специальное имеет - DTO (DataTransferObject), паттерн. Но путать DTO и обьекты не стоит, т.к. по факту это структуры данных. В С#, С и каких нибудь еще языках для этого есть даже ключевое слово struct, но в пыхе мы такого не имеем по этому заворачиваем в обьекты.
кстати, как называется этот слой приложения, и в чьей зоне ответственности эта задача
Зависит от вашей архитектуры. Если у вас богатая доменная модельно, то эти методы выборки и создания могут быть прям в модели, если у вас анемичная модель, то существует слой бизнес сервисов в которые выносятся методы работы с вашей бизнес логикой.
Меня смущает множество классов, которые в себе очень редко содержат какую-то бизнес-логику, судя по этому у вас как раз второе. Однако сама выборка из базы это явно не зона ответственности модели, для этого не плохо бы вынести это всё дело в persistanse слой.