Прежде всего, на мой взгляд, я бы хотел предложить вам не думать о реляционном дизайне, основанном на объектно-ориентированном программном решении.
Принимая последнее предложение за истину, я буду подсказывать, что каждый тип сущности имеет какое-то отношение к бизнесу, вы разработаете таблицу данных для него.
Во всяком случае, я считаю, что вы могли бы иметь другой реляционный дизайн. Почему бы вам не создать такую таблицу «Пользователи», которая содержит базовую информацию, такую как уникальный идентификатор, учетные данные - и любую другую базовую информацию, которая понадобится вам для идентификации, аутентификации и авторизации пользователя -?
Имея это, вы создадите реляционную таблицу под названием "TrainerUsersProfiles", "PlayerUsersProfiles" и т. Д.
Фактически, «TrainerUsersProfiles», «PlayerUsersProfiles» - это что-то вроде данных профиля, потому что вы должны быть пользователем, чтобы проходить аутентификацию и быть авторизованными для ресурсов приложения. Но пользователь может иметь больше связанной информации, скажем, «профиль». Любая информация в качестве тренера или игрока является частью профиля пользователя.
Теперь пришло время узнать, какие атрибуты являются общими для тренеров и игроков (и любых других). Такие общие атрибуты должны быть в таблице профиля пользователя «UsersProfiles», которая имеет отношение один к одному с конкретным пользователем.
Например, я бы поместил любые расширенные данные профиля в «TrainerUsersProfiles» и «PlayerUsersProfiles», и оба (или более) будут иметь отношение один к одному с некоторым профилем пользователя.
Подведение итогов: у пользователя есть профиль, а в профиле - расширенные специализированные данные профиля.
Говоря об объектно-ориентированном слое - приложении - я хотел бы предложить, что лучше избегать этой абстрактной фабрики и просто использовать репозиторий:
userRepository.GetById([id])
Пользовательский класс будет иметь свойство "Kind", которое является перечислением видов профиля пользователя (Trainer, Player и т. Д.).
Кроме того, класс User будет иметь свойство "Profile", которое также должно иметь свойство "Properties". «Свойства» относятся к типу, называемому «ProfileProperties», и есть «TrainerProperties» и «PlayerProperties», получающие его.
Наконец, это будет пример использования:
User someUser = userRepository.GetById([id]);
string somePropertyValue = null;
switch(someUser.Kind)
{
case Trainer:
somePropertyValue = ((TrainerProperties)someUser.Profile.Properties).SomeTrainerProperty;
break;
case Player:
somePropertyValue = ((PlayerProperties)someUser.Profile.Properties).SomePlayerProperty;
break;
}
Я считаю, что это может быть вашим правильным решением, и оно может закончиться хорошим реляционным и объектно-ориентированным дизайном.