10

現在、テーブルごとのタイプ (TPT) を使用して Entity Framework 4.0 モデルを配置していますが、いくつかのパフォーマンスの問題 (多くの LOJ/CASE ステートメント) と、2 つの特定のドメイン領域間の問題のマッピング (多対多) があります。たくさんの)。

TPHを試してみることにしました。

私は「Location」という抽象的エンティティと、他のすべてのエンティティのベースとなるエンティティを持っています。

次に、「Country」、「City」、「State」、「Street」などをすべて Location から派生させます。

LocationType」は識別子です。

その部分は正常に機能していますが、派生型のナビゲーション プロパティを定義しようとして問題が発生しています。

たとえば、「」には単一の「」があるため、これを実行できるはずです。

var state = _ctx.Locations.OfType<State>().Include("Country").First();
var countryForState = state.Country;

ただし、これには、"State" 派生エンティティの "Country" というナビゲーション プロパティが必要です。どうすればいいですか?データベースからモデルを生成すると、すべての FK が同じテーブル内のレコードを指している単一のテーブルがあります。

代替テキスト

(注: これらの FK は DB で手動で作成しました)。

しかし、FK は " Location " エンティティのナビゲーションとして配置されているため、これらのナビゲーション プロパティを派生エンティティに移動するにはどうすればよいでしょうか? ナビゲーションをコピーして貼り付けることはできません。開始/終了の役割を定義できないため、「新しいナビゲーション プロパティを作成する」こともできません。

どうやってこれを行うのですか?

また、モデル ファーストで実行できるかどうか、または DB から開始し、モデルを修正してから DB を再生成する必要があるかどうかも、TPH では明確ではありません。TPH の子供のナビゲーションを定義する方法について、インターネット上で良い例をまだ見つけていません。

注: code-first を実行したくありません。私の現在のソリューションには、EDMX を使用した TPT と純粋な POCO があります。(可能であれば) ドメイン モデル/リポジトリに影響を与えず、EF モデル/データベースを更新することを望んでいます。

編集

まだ解決策はありませんが、モデルを最初に実行しようとしていて、[追加] -> [新しい関連付け] を実行しています。これにより、実際には、派生エンティティにナビゲーションを追加できます。しかし、「モデルからデータベースを生成」しようとすると、「Location_Street」、「Location_Country」などのテーブルを作成しようとします。最初にモデルを作成できないようです。

編集

これが私の現在のモデルです:

代替テキスト

現在取得している検証エラー:

エラー 1 エラー 3002: 359 行目から始まるフラグメントのマッピングの問題: テーブルの場所のキー (Locations.LocationId) のランタイム違反の可能性: 列 (Locations.LocationId) は、概念側で EntitySet NeighbourhoodZipCode のプロパティ (NeighbourhoodZipCode.Neighbourhood.LocationId) にマップされますただし、それらは EntitySet のキー プロパティ (NeighbourhoodZipCode.Neighbourhood.LocationId、NeighbourhoodZipCode.ZipCode.LocationId) を形成しません。

私が現在どこにいるかに関する編集でこの質問を編集し続けると思っただけです。自己参照 FK を使用した TPH が可能であるかどうか疑問に思い始めています。

編集

だから私は上記のエラーを見つけました。これは、Neighbourhood-ZipCode 多対多の結合テーブルが欠落していたためです。

結合テーブルを追加して(そしてそれにナビをマッピングして)上記のエラーを解決しました。

しかし、今はこのエラーが発生しています:

エラー 3032: 行 373、382 で始まるフラグメントのマッピングに問題があります: 条件メンバー 'Locations.StateLocationId' に重複した条件値があります。

CSDL を見ると、「CountyState」の関連付けマッピングは次のとおりです (州には多くの郡があり、郡には 1 つの州があります)。

<AssociationSetMapping Name="CountyState" TypeName="Locations.CountyState" StoreEntitySet="Locations">
   <EndProperty Name="State">
      <ScalarProperty Name="LocationId" ColumnName="StateLocationId" />
   </EndProperty>
   <EndProperty Name="County">
      <ScalarProperty Name="LocationId" ColumnName="LocationId" />
   </EndProperty>
   <Condition ColumnName="StateLocationId" IsNull="false" />
</AssociationSetMapping>

関連付けもこの状態であるため、Condition ColumnName="StateLocationId"それは不平を言っていることです。ZipCodeState

しかし、私はそれを取得しません。すべてのエンティティの識別子は一意であり (トリプル チェック済み)、これは有効なシナリオだと思っていたでしょう。

  1. 郡には、StateLocationId (場所テーブル) で示される単一の州があります。
  2. ZipCode には、StateLocationId (Locations テーブル) で示される単一の State があります。

それはTPHでは有効ではありませんか?

4

1 に答える 1

5

それで、いくつかの問題を解決しましたが、レンガの壁にぶつかりました。

まず、データベース側で自己参照 FK を作成するときに、「データベースからモデルを更新」しようとすると、Entity Framework はこれらのナビゲーション プロパティをメインの基本型に追加します。これは、TPH の明示的な意味がないためです。モデル側でこれを行う必要があります。

ただし、ナビゲーション プロパティを子タイプに手動で追加することはできます。

このエラーを WRT します。

エラー 3032: 行 373、382 で始まるフラグメントのマッピングの問題: 条件メンバー 'Locations.StateLocationId' に重複した条件値があります。

これは、「ZipCode_State」関係と「City_State」関係に使用しようとしていた「Location_State」という FK があったためです。これは機能しません (理由はまだわかりません)。

それを解決するために、追加の列と追加の FK を追加する必要がありました。1 つは「ZipCode_State」と呼ばれ、もう 1 つは「City_State」と呼ばれます。明らかに、nav と物理 FK の間は 1-1 でなければなりません。

Location.LocationType にはデフォルト値がなく、null 可能ではありません。エンティティ データを格納するには、列の値が必要です。

それが私の識別フィールドです。データベース側では、 nullable ではありません

この問題に関するスレッドを読んだところ、リレーションシップを 0..* から 1..* に変更する必要があるとのことでしたが、私のリレーションシップはすでに 1..* でした。

上記の「場所」の実際のデータベース テーブルを見ると、すべての FK が null 可能です (そうである必要があります)。したがって、私の関係は 0..* であるべきかどうか疑問に思い始めました。

ただし、TPH のため、それらは null 可能です。すべての「場所」に「状態」があるわけではありません。しかし、その場所が「都市」である場合、「州」が必要です。

私の気持ちは、この SO の質問によってさらに慰められました: ADO EF - TPH の派生型間の関連付けをマッピングするエラー

私は実際にその回避策を試していましたが(遭遇する前に)、回避策はうまくいきません。すべての関係を 1..* から 0..* に変更しようとしましたが、それでもうまくいきません。

ここで時間を無駄にしすぎて、TPT に戻りました。

結局のところ、TPH を使用すると、非常に大きなテーブルがあり、冗長で null 可能な列がたくさんあります。JOINに関しては、より効率的です。しかし、少なくとも TPT では、null 可能で自己参照する FK を使用する必要はありません。

誰かがこの問題の解決策を持っている場合は、私に知らせてください。しかし、それまではTPTを使い続けます。

于 2010-11-26T05:46:16.447 に答える