零或一对一或一个关系问题

时间:2013-12-22 20:18:22

标签: sql-server entity-framework database-design relational-database visual-studio-lightswitch

使用能够生成代码的数据库建模工具时,某些关系类型(几乎?)从不支持。

它们包括1对1,多对多,0或1对0或1. 1:1,和0..1:0 .. 1。

前两个有简单的解决方案。

  1. 1-to-1可以通过转换为0..1-to-1或1-to-0..1,0..1:1或1:0..1来解析。 / p>

  2. 可以通过在关系中间使用表来解析多对多,然后使用1:*和:1或0..1:和a *:0..1或类似的组合。我认为有四种可能的组合来解决它。

  3. 然而,我被困在0..1到0..1。事实上,我有这样一组似乎具有这种逻辑关系的表。

    在我的情况下,我有四张桌子。为了论证,假设它们都具有INT类型的主键。表格是人员,组织,客户和员工。

    关于逻辑的一个词。组织可以拥有人,他们在关系中称为联系人。人们既可以是客户,也可以是员工,或两者兼而有之。

    组织< - >有联系人< - >作为人。这是一个0..1:*的关系。这意味着一个人可以在有或没有组织的情况下存在,并且一个组织可以有很多人(或没有人)。

    员工必须拥有个人记录,这种关系也是有意义的。它是0..1:1关系,其中Employee必须有Person,但Person可以有0或1个Employee记录。

    但是这个没有意义,因为实体继承在逻辑上沿两个方向流动。对于客户的人员或组织。客户可以是组织或个人,但不能同时是两者,并且选择是通过类型标志字段进行的。同一个人不一定是客户,以后可能是员工或其他一些联系方式。我不能要求某人成为客户,我也不能要求客户成为客户。同样,我不能要求组织成为客户,也不能要求客户成为组织。因此,继承的断开也是必要的。对于Customer:Person和Customer:Organization,它们都需要实现0..1:0..1和0..1:0..1。但语言工具不支持它。因为它们是强类型语言,所以实体继承只能在单个方向上流动。即使是弱类型的语言,你仍然会在最先出现的情况下结束:鸡肉或鸡蛋。

    JavaScript可能非常适合这种情况,因为您可以动态地更改对象类型的结构,并且您始终可以按任意顺序组合这两个结构,即使您无法以这种方式显式声明对象存在

    但我今天使用的工具是Microsoft LightSwitch,它根本不会这样做。我不认为现有的建模工具会产生强大类型的语言代码,并允许这种关系类型。

    有没有一个技巧可以克服这种关系,0..1:0..1,还是有一些基本的东西我还没有理解?我被留在这里选择一方,我不知道哪一方获胜:客户或个人,客户或组织。但也许我还能做其他事情,而不会妥协任何一种情况。有没有关于模型被破坏的东西?

    谢谢!

1 个答案:

答案 0 :(得分:0)

0..1模型通常是is-a关系。这映射到C#中的继承。在C#中,您无法创建从多个其他类继承的类(仅通过接口)

您的模型纯粹建模为关系数据库,但它不映射到没有多重继承的对象结构。在C#中定义一个有效的模型(使用继承和关系),然后为它生成一个Datamodel,因为在这种情况下C#是限制因素。

请记住,您可以使用继承:

Customer
<--is-a- Corporate Customer --has-a-- Organization --has-many-|
<--is-a- Natural Customer   --has-a-- Person    <--is-a- Employee

在这种情况下,您将无法直接向个人或组织投射Customer,但您可以访问与此课程相关联的记录,这对我来说很自然。但是员工总是一个人(这是有道理的)。

如果您愿意,可以从Organization继承PersonLegalEntity。在上面的模型中(保留Natural/Corporate Customer),

Customer<T:LegalEntity> -----------has-a--------------- LegalEntity
 ^                                                              ^  
 |--is-a- Customer<Organization> (--has-a--) Organization -is-a-|  --has-many
 L--is-a- Natural<Person>        (--has-a--) Person -------is-a-|       |
                                               ^                        |
                                               L--is-a- Employee -------|

但在这种情况下你还可以进一步简化模型:

Customer
  |--has-a LegalEntity <---is-a-- Organization --has-many-|
                         L-is-a-- Person    <--is-a- Employee

或者您可以使用Person作为基础,但这会导致更丑陋的模型:

Person
<- Employee ---- Organization  <- Corporate Customer
<- Natural Customer ----|              |
          |                            |
          L------------------------------->> ICustomer

在这种情况下,您的Person可以是EmployeeNatural Customer(但不是两者),另外,您无法创建包含Customer的{​​{1}}列表除了通过接口之外,Natural CustomerCorporate Customers都有,但实体框架并不总能理解这些。这个模型感觉很尴尬,但似乎更接近你现在的模型。

无法使用.NET或Entity Framework构建所需的完整保真度模型。