Database design 数据库中保存的不同用户类型的Factory模式

Database design 数据库中保存的不同用户类型的Factory模式,database-design,inheritance,persistence,design-patterns,Database Design,Inheritance,Persistence,Design Patterns,我有一个问题以前必须回答好几次,但我找不到任何好的搜索词来找出解决这个问题的最佳方法 在我的应用程序中,我将拥有不同类型的用户,这些用户将具有不同的属性和方法,但其中大部分也是相同的。所以我创建了一个基类“用户”和其他类“玩家”、“教练”等等。。。从“User”类继承的 我应该如何将其保存在数据库中,保存在一个名为“User”的巨大表中,该表具有所有类的所有不同属性,还是我的数据库看起来像我的类?我认为解决方案2更好 我将只有一个登录方法,因此它将始终返回基类,但是当使用不同的特定类型(“pla

我有一个问题以前必须回答好几次,但我找不到任何好的搜索词来找出解决这个问题的最佳方法

在我的应用程序中,我将拥有不同类型的用户,这些用户将具有不同的属性和方法,但其中大部分也是相同的。所以我创建了一个基类“用户”和其他类“玩家”、“教练”等等。。。从“User”类继承的

我应该如何将其保存在数据库中,保存在一个名为“User”的巨大表中,该表具有所有类的所有不同属性,还是我的数据库看起来像我的类?我认为解决方案2更好

我将只有一个登录方法,因此它将始终返回基类,但是当使用不同的特定类型(“player”、“trainer”)时,将对该类进行转换。但是我如何调用数据库来填充我的不同类

我能做的是,在用户表中,类型也被保存。当我将该信息返回到我的代码中时,我检查类型是什么,然后调用数据库获取该类型的特定信息,创建正确的类型并在代码中作为“用户”返回。但是我不喜欢这样的想法,我需要两次调用数据库来用数据填充我的对象,我可以用SP来解决它,但我尽量不使用SP

当我不知道调用数据库时将返回什么类型时,有没有一个好方法可以通过一次对数据库的调用来解决这个问题

感谢您的帮助。

这称为“多态持久性”。有多种方法可以做到这一点。它们都有一个共同点,即基表中有一列,每行包含对象的真实类

OR映射器使用此列加载同一表中的更多列,或连接其他表中的列


看。这里有一个。

首先,在我看来,我想建议您不要将基于面向对象软件解决方案的关系设计放在上面

假设最后一句话是真的,我的提示是在业务中有事情要做的每种类型的实体,您将为其设计一个数据表

无论如何,我发现你可以有另一个关系设计。为什么不创建这样一个“用户”表,其中包含诸如唯一标识符、凭证等基本信息,以及用户标识、身份验证和授权所需的任何其他基本信息

有了它,您就可以设计一个名为“TrainerUsersProfiles”、“PlayerUsersProfiles”等的关系表

事实上,“TrainerUsersProfiles”、“PlayerUsersProfiles”类似于配置文件数据,因为您必须是用户才能对应用程序的资源进行身份验证和授权。但是用户可以有更多的相关信息,比如说“个人资料”。作为教练或球员的任何信息都是用户档案的一部分

现在是时候找出哪些属性在教练和球员(以及任何其他人)身上是共享的了。此类共享属性应位于用户的配置文件表“UsersProfiles”中,该表与特定用户具有一对一的关系

例如,我将任何扩展配置文件数据放在“TrainerUsersProfiles”和“PlayerUsersProfiles”中,这两个(或更多个)都与某个用户配置文件有一对一的关系

概述:用户有一个配置文件,配置文件有一个扩展的、专门的配置文件数据

谈到面向对象层(即应用程序),我建议最好避免使用抽象工厂,只使用存储库:

userRepository.GetById([id])
用户类将有一个“Kind”属性,它是用户配置文件类型(培训师、玩家等)的枚举

此外,用户类将有一个“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;
}

我相信这可能是您正确的解决方案,它可以以良好的关系和面向对象的设计结束。

这听起来很有趣,它还解决了我遇到的另一个问题,即用户可以既是玩家又是培训师。通过添加一个配置文件列表,我可以解决这个问题,甚至在将来,让用户成为球员/教练/推荐人或其他任何人……是的,这就是这个解决方案的重点。很高兴知道它对您的解决方案很有用!