我相信,我有一个与TPH有关的问题。这是场景: 我们有一个名为Artists的表,它有一些关于艺术家的属性(如名称,minibio等)和一个字节字段,其中的位用于确定艺术家的类型,其值如下:
1 - Singer
2 - Actor
4 - Composer
8 - Musician
16 - Director
请注意,同一位艺术家可能只是一种或属于多种。我们来看一个例子:
+-------------------------------------------------+
| Table: Artist |
+---------------------------------------+---------+
| Name | Kind |
+---------------------------------------+---------+
| Al Pacino | 2 | (Actor)
+---------------------------------------+---------+
| Mel Gibson | 18 | (Actor and Director)
+---------------------------------------+---------+
| Dave Matthews | 15 | (Actor, Singer, Composer and Musician)
+---------------------------------------+---------+
现在,我可以使用存储过程的可更新视图(对于CRUD)来执行TPH 我也知道这是不可能的(至少对我来说!)使用条件映射来做这个,因为我不能使用带有按位OR的表达式,如条件中的“(Kind | 2)= 2”。
我一直认为,通过将de field Kind分成以下内容来改变表结构:
+-----------------------------------------------------------------------------------------+
| Table: Artist |
+---------------------------------------+-------+--------+----------+----------+----------+
| Name | Actor | Singer | Composer | Musician | Director |
+---------------------------------------+-------+--------+----------+----------+----------+
| Al Pacino | 1 | 0 | 0 | 0 | 0 |
+---------------------------------------+-------+--------+----------+----------+----------+
| Mel Gibson | 1 | 0 | 0 | 0 | 1 |
+---------------------------------------+-------+--------+----------+----------+----------+
| Dave Matthews | 1 | 1 | 1 | 1 | 0 |
+---------------------------------------+-------+--------+----------+----------+----------+
可以工作,但是这样做,虽然我可以使用条件映射中的字段创建TPH,但EF(显然)给出了一个错误,指出派生实体(Actor,Singer等)是
映射到表Artist中的相同行。
我的问题是,还有其他方法吗?
提前致谢。
答案 0 :(得分:1)
您建议的映射既不是TPH也不是关系。你也很难将这样的模式映射到任何好的OO模型。您可能还发现很难有效地查询这样的DB。在TPH方案中,鉴别器字段包含表示一个类型的单个标量值。这是必要的,因为任何实例只能有一种类型。实例的类型永远不会在其生命周期中发生变化,并且当您将实例持久化到数据库时,实例的生命周期实际上是永久的。
所以:我认为以EF会理解的任何方式绘制这样的方案是相当困难的,我认为这不值得付出努力。如果这是遗留数据,请在DB或EDMX中进行查看。如果它是一个新的应用程序,我认为你需要重新考虑你的架构,并提出一个适合OO和关系模型的模型。
答案 1 :(得分:0)
在这种情况下,我认为你应该尊重“构成而非继承”。 如果一个人可以同时成为歌手和演员,那么继承显然是数据结构的错误选择。