EntityFramework(CodeFirst)继承映射:TPT和TPC的混合

5
我们正在创建一个EntityFramework CodeFirst数据访问层,用于访问一个“遗留”的数据库(这意味着我们大多数时候只能使用该数据库中存在的设计错误)。
领域模型(相当)简单:我们有抽象的Card,分为HomeCard、CarCard、OwnerCard和RenterCard。具体来说:
abstract class Card {}
class HomeCard: Card {}
class CarCard: Card {}
class OwnerCard: Card {}
class RenterCard: Card {}

数据库模型包含了Cards、Homes、Cars、Owners和Renters这些表,其中Cards包含常见的列,其他表包含特定类别的列。这正是TPT所指的内容,它与EntityFramework完美地映射在一起。

在重构后,我们发现(不出所料)Home和Car有一些共同属性,Owner和Renter也是如此。这不仅仅是为了美观,而且某些功能实现起来会更加容易(例如按名称搜索Owners和Renters,或者按所有者搜索Homes和Cards)。因此,我们希望我们的领域模型看起来像这样:

abstract class Card {}
abstract class ProperyCard: Card {}
class HomeCard: ProperyCard {}
class CarCard: ProperyCard {}
abstract class PersonCard: Card {}
class OwnerCard: PersonCard {}
class RenterCard: PersonCard {}

但是我们仍然有相同的数据库模型,这意味着我们在TPT和TPC之间有一些奇怪的混合。我们尝试通过EF/CodeFirst进行映射,但都失败了。有什么建议可以使其正常工作吗?

PS 我们的基本表Cards确实有一个鉴别器字段,如果有帮助的话。


你为什么要尝试使用Code First来操作现有的数据库? - podiluska
因为我喜欢映射的描述方式。本质上它并不是“代码优先”,而是“代码即模型”。 - Sergei Rogovtcev
2
我认为你无法使用EF将其映射,因为你的中间类不是真正的实体。 - Ladislav Mrnka
@LadislavMrnka 坦白地说,这也是我所期望的。但我希望如果有答案,社区会知道它。 - Sergei Rogovtcev
嗨Serg,我认为鉴别器字段是你最好的选择。将其映射到一个枚举上,你可以进行按位比较。例如CardType.Property | CardType.Home等等...这对你有用吗? - ZagNut
@ZagNut 不会的。我需要类层次结构,而不是区分实体的方法。 - Sergei Rogovtcev
1个回答

0

您已经有一个现有的数据库,因此不想使用Code First。将实体数据模型项添加到您的项目中,并使用提供的向导将其连接到现有的数据库。

我不建议以下操作但如果您必须让您的CF模型与现有数据库配合,请尝试以下步骤。

  1. 让CF生成一个新的数据库。
  2. 将EDMMetaData(<EF4.3.1)或__MigrationHistory(>=EF.4.3.1)表复制到现有的数据库中。这将欺骗EF认为它创建了DB并且匹配。

注意:当使用CF框架针对您的旧数据库进行工作时,您很可能会在后面遇到错误。如果您的CF框架不是完美的,它将受到影响。


想要使用CodeFirst,因为它有完全不同的映射模型。在我看来,这个名称总是不对,应该叫CodeOnly而不是CodeFirst - Sergei Rogovtcev
@SergRogovtsev 请查看修改。我已经提出了一个建议,可以“欺骗”您的CF框架使用您的旧数据库。 - Paul Fleming
你没有理解我的问题。我并不难让EF/CF认为它与数据库匹配。我的问题是,我们还没有找到支持我们特定继承场景的工作映射配置。 - Sergei Rogovtcev
我正在使用现有的数据库,Code First 对我非常有效。由于存在错误和EDM配置的复杂性,我在使用EF设计器时遇到了各种问题。你只需要基本上删除初始迁移中的所有内容,并确保初始数据模型完美地映射到数据库即可。一旦完成这些步骤,你的模型就是一个有效的Code First模型。 - HiredMind

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接