Лично я предпочел бы сохранить отдельные сущности / отношения, если есть какая-либо вероятность, что связанные сущности (утверждения) могут каким-либо образом отличаться в зависимости от того, к чему они применяются. Я избегаю двусмысленно связанных таблиц, если только они не представляют большую сущность 1 ко многим, которая может быть связана с одной или несколькими другими сущностями.
Проблема с использованием чего-то вроде «ParentType» + «ParentId» заключается в том, что вы не может использовать любую форму ограничения FK между связанными таблицами. Это также означает, что вы не можете использовать отношения EF, поскольку, вероятно, будет время загружать один из документов и пытаться узнать, одобрен ли он, и подробности из утверждения.
Если ожидается утверждение для различных типов документов то же самое, я бы скорее объявил общую таблицу утверждения / сущность и поместил ApprovalId в каждую из таблиц типов документов, чтобы установить sh отношение многие-к-1 от документа к утверждению.
Если утверждение идентично и может образовывать множество ко многим, то может быть использована подходящая таблица отношений многие ко многим DocumentLetter - DocumentLetterApproval (FKs) - Approval (Сведения об утверждении).
Если утверждение Письмо и другое утверждение могут отличаться, тогда: DocumentLetter - DocumentLetterApproval (сведения об утверждении)
Подобные решения по проектированию обычно основываются на соображениях DRY (не повторяйте себя). Совет, который я могу дать, заключается в том, что KISS («Держите это тупо простым») должно превосходить DRY, и что DRY должно применяться только к логике / структуре, которая доказала свою идентичность. (не просто ожидается, что они будут идентичными, или, что еще хуже, ожидается, что они будут похожи) DRY должно быть фактором, учитывающим повторный факторинг, для постоянного улучшения, а не предварительным проектным решением. Кодирование для DRY слишком рано в конечном итоге стоит вам времени, когда вы рисуете себя в углах. Сохраняя текучесть кода, эти отношения можно доказать, а затем, если они окажутся идентичными, повторно проанализировать в единую сущность. Время по-прежнему тратится на перефакторинг, но перефакторинг, чтобы сделать структуру кода лучше, а не ухудшать код, когда приходится обходить допущения при проектировании.
Примером, в котором я мог бы рассмотреть неоднозначную слабо связанную связанную таблицу, будет что-то вроде файловых вложений. У меня может быть несколько сущностей, которые могут содержать ссылки на 1 или более вложений. Вложения - это не то, на что мне нужно было бы часто ссылаться, а скорее через явное действие, которое я мог бы запустить для любого запроса в любом случае, так как я не собираюсь предварительно загружать детали вложения при загрузке документа. В этом случае таблица вложений может иметь индексированные ParentType и ParentId, чтобы я мог быстро получить подробную информацию для конкретного документа или другого объекта. Я бы никогда не попытался сделать что-то вроде Context.Documents.Include(x => x.Attachments)
или тому подобное, такой ссылки не было бы. Вложения всегда будут доступны по одному документу, поэтому я прибегну к Context.Attachments.Where(x => x.ParentType == ParentTypes.DocumentLetter && x.ParentId == documenLetterId).ToList();
У меня есть опыт работы с системами, которые были разработаны исключительно с этими типами неоднозначно связанных таблиц. Они не только чрезвычайно медленны, поскольку они масштабируются до любого разумного размера, но они также чрезвычайно подвержены ошибкам по мере развития систем и изменения характера отношений. Записи имеют тенденцию выходить из строя c с ожидаемыми правилами.