繁体   English   中英

实体框架与TPH的多级继承

[英]Entity Framework Multi-level Inheritance with TPH

我正在使用遗留系统,为一定数量的项目实现TPH。 所以目前的结构看起来像这样

 Abstract Class 1     Abstract Class 2     Abstract Class 3
         |                    |                    |
     ---------            ---------            ---------
    |    |    |          |    |    |          |    |    |
    T1   T2   T3        T4    T5   T6         T7   T8   T9

因此Type(T *)是所有表中的鉴别器,但由于某些类型共享公共列,因此存在大量不同的表。 问题是所有这些项目实际上都有一个共同点,但没有办法将所有这些项目收集到一个集合中。 实际上,层次结构实际上看起来应该更像这样。

          --------------- Base Abstract 1 ---------- 
         |                    |                    |
 Abstract Class 1     Abstract Class 2     Abstract Class 3
         |                    |                    |
     ---------            ---------            ---------
    |    |    |          |    |    |          |    |    |
    T1   T2   T3        T4    T5   T6         T7   T8   T9

基本上我们所拥有的是TPT,其中每种类型的每个表都是TPH。 对于一个真实世界的例子,这是我们需要的。

          ---------------  Vehicle   --------------- 
         |                    |                    |
        Car                 Boat                 Plane
         |                    |                    |
     ---------            ---------            ---------
    |    |    |          |    |    |          |    |    |
   BMW Toyota Fiat      T4   T5   T6         T7    T8   T9

显然,初始设计存在一些设计缺陷,没有人预计需要在不查询3个不同表格的情况下获取所有车辆的列表。 所以我的问题是,现有的结构有一种方法可以将这种新的层次结构添加到实体框架中。 我在想这样的事情

  Vehicle
  -------
  VehicleId
  TypeId (Boat, Plane, Car, etc)
  ItemFK (BoatID, PlaneId, CarId)

这可能吗? 有没有办法在实体框架中映射这些? 我似乎无法正确匹配它们。 如果我们用VehicleId替换BoatId,PlaneId和CarId似乎可能有用(比如实体框架中的条件映射 - 或者使用TPH进行操作 )但是在那时我们将进行真正的侵入式模式更改,这实际上不是选项,我不确定它是否会奏效。 基本上我需要一种方法将现有密钥映射到新的层次结构。 任何帮助是极大的赞赏。 我很茫然,似乎无法找到解决我问题的任何解决方案。

你可以使用这个结构

在此输入图像描述

 public class Vehicle
    {
        [Key]
        public int Id { set; get; }

        ///
        // common properties
        ///

        public Car Car { set; get; }
        public Boat Boat { set; get; }
        public Plane Plane { set; get; }
    }

    public class Car
    {
        [Key, ForeignKey("Vehicle")]
        public int VehicleId { set; get; }
        public Vehicle Vehicle { set; get; }

        ///
        // Car properties
        ///
    }

    public class Boat
    {
        [Key, ForeignKey("Vehicle")]
        public int VehicleId { set; get; }
        public Vehicle Vehicle { set; get; }

        ///
        // Boat properties
        ///
    }

    public class Plane
    {
        [Key, ForeignKey("Vehicle")]
        public int VehicleId { set; get; }
        public Vehicle Vehicle { set; get; }

        ///
        // Plane properties
        ///
    }

问题是所有这些项目实际上都有一个共同点,但没有办法将所有这些项目收集到一个集合中。

也许你可以在每个层次结构中有类型实现一个通用接口? 由于每个层次结构都已经是一个单独的表,因此通过添加公共基类似乎不会获得太多 - 而且似乎不值得麻烦。

可以根据您在DbContext定义的DbSet<>来定义TPH / TPC约定。 例如,代替声明DbSet<>每派生类型T ,只声明一个DbSet<>对于每个抽象类型。 然后,您可以使用相应的DbSet<>或使用基本抽象类型的DbSet<>的所有抽象类单独查询抽象类。

基本抽象类必须至少定义一个字段,因此Code-First Migrations将为该类型生成一个表。 要定义的最合理的字段是PK。 但是,由于抽象类之间的PK冲突(正如您在评论中所述),当前数据的迁移将不起作用。

另一种可能性是,当您查询基本抽象类型的DbSet<>时,实体框架将正确查询所有抽象类型,即使数据库中没有基本抽象类型的表(因为基本抽象类型没有定义字段) 。 但是,我之前没有遇到过这种情况,所以我不能肯定地说它是否会起作用。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM