Может ли у работника быть несколько непосредственных руководителей
Что проверяют
Обычно это уточнение в задаче на проектирование схемы или SQL вроде «выведите всех подчинённых руководителя». Интервьюер смотрит, выясняете ли вы требования до того, как рисовать модель, потому что от ответа зависит, дерево у вас или граф. Следом просят показать обе модели в EF Core и написать иерархический запрос.
Как отвечать
В реальных компаниях да: матричная структура с функциональным и проектным руководителем, замещение, совместительство. Уточните, нужен ли этот сценарий, и покажите, как ответ меняет модель.
- один руководитель: самоссылка
ManagerId int?в таблицеEmployees. В EF Core:HasOne(e => e.Manager).WithMany(e => e.Subordinates).HasForeignKey(e => e.ManagerId). Это дерево, у корняManagerIdравенNULL; - несколько руководителей: связующая таблица
EmployeeManagers (EmployeeId, ManagerId, Role, ValidFrom, ValidTo). В EF Core это многие-ко-многим черезUsingEntity<EmployeeManager>(), и сущность связи оправдана, у неё свои поля: тип руководства и период; - иерархические запросы: рекурсивное CTE. В SQL Server пишется просто
WITH, в PostgreSQLWITH RECURSIVE. Для дерева в SQL Server есть типhierarchyid, EF Core поддерживает его начиная с восьмой версии, но он описывает только дерево и для графа не подходит.
Обязательно назовите инварианты: нельзя быть руководителем самому себе, в графе не должно быть циклов (A руководит B, B руководит A), а при нескольких руководителях часто нужен признак основного, чтобы было понятно, кто согласует отпуск.
Где спотыкаются
Молча рисуют ManagerId. Потом появляется второй руководитель, и приходится мигрировать данные и запросы.
Оставляют каскадное удаление по умолчанию в связующей таблице. У EmployeeManager два обязательных внешних ключа на Employees, EF Core делает оба каскадными, и SQL Server отклоняет миграцию с ошибкой про циклы или несколько путей каскада. Нужен OnDelete(DeleteBehavior.Restrict) или NoAction.
Пишут рекурсивное CTE без защиты от циклов. На графе с ошибкой в данных запрос упрётся в лимит рекурсии (в SQL Server по умолчанию 100) или в PostgreSQL будет крутиться бесконечно.