10

特定の数のアイテムに対して TPH を実装するレガシー システムを使用しています。したがって、現在の構造は次のようになります

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

したがって、タイプ (T*) はすべてのテーブルの識別子ですが、特定のタイプは共通の列を共有するため、かなりの数の異なるテーブルがあります。問題は、これらすべての項目が実際には小さな共通点を共有していることですが、これらの項目すべてをコレクションに集める方法がないことです。実際には、階層は実際にはこのように見えるはずです。

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

したがって、本質的には、タイプごとの各テーブルが TPH である TPT です。実際の例として、必要なものは次のとおりです。

          ---------------  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)

これは可能ですか?これらをエンティティ フレームワークにマップする方法はありますか? それらを正しく一致させることはできません。BoatId、PlaneId、および CarId を VehicleId ( Entity Framework の条件付きマッピング - または TPH での操作など) に置き換えるとうまくいく可能性がありますが、その時点で、実際にはそうではない非常に侵襲的なスキーマ変更を行うことになります。オプションであり、それが機能するかどうかはわかりません。基本的に、既存のキーを新しい階層にマップする方法が必要です。どんな助けでも大歓迎です。私は途方に暮れていて、私の質問に答える解決策が見つからないようです。

4

3 に答える 3

1

この構造を使用できます

ここに画像の説明を入力

 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
        ///
    }
于 2016-07-03T04:30:02.073 に答える
0

TPH/TPC 規則は、 で定義した に基づいて定義できDbSet<>ますDbContext。たとえば、DbSet<>per 派生型を宣言する代わりに、 for each 抽象型Tのみを宣言します。DbSet<>次に、対応する抽象クラスを使用して抽象クラスを個別に照会するか、基本抽象型の をDbSet<>使用してすべての抽象クラスを照会できます。DbSet<>

Code-First Migrations が型のテーブルを生成するように、基本抽象クラスには少なくとも 1 つのフィールドが定義されている必要があります。定義する最も論理的なフィールドは PK です。ただし、(コメントで述べたように) 抽象クラス間の PK の衝突のため、現在のデータの移行は機能しません。

DbSet<>もう 1 つの可能性は、基本抽象型のテーブルがデータベースに存在しない場合でも、基本抽象型のクエリを実行すると、Entity Framework がすべての抽象型を適切にクエリすることです(基本抽象型にはフィールドが定義されていないため)。ただし、これまでにこのシナリオに遭遇したことがないため、うまくいくかどうかは断言できません。

于 2015-09-29T00:13:16.143 に答える
0

問題は、これらすべての項目が実際には小さな共通点を共有していることですが、これらの項目すべてをコレクションに集める方法がないことです。

おそらく、各階層の型に共通のインターフェイスを実装させることができますか? 各階層はすでに個別のテーブルであるため、共通の基本クラスを追加してもあまりメリットがないように思われます。

于 2015-08-06T06:35:53.307 に答える