3

私はすでにEntity Framework One-To-One Mapping Issues を読みましたが、ここではビジネス ルールの仕様が異なるため重複していません。

Invoices と Orders の 2 つのテーブルがあります。

Invoices
-> InvoiceID (Primary, Auto Number)
Orders
-> OrderID (Primary, Auto Number)
-> InvoiceID (FK InvoiceID of Invoices Table)

問題は、プロパティの名前が同じでない場合、EF はこの関連付けに 1 対多の関係を必要とすることです。プロパティの名前が同じであれば、派生クラスの目的を果たしますが、ここでは Order は派生クラスでも請求書でもありません。

InvoiceID はショッピング カートごとに生成されますが、OrderID は支払い済みの請求書に対してのみ生成されるため、すべての注文に InvoiceID がありますが、すべての注文に対応する請求書はありません。

このために別のテーブルを作成すると、それを行うにはあまりにも多くのコードを書かなければなりません。この制限を削除して、EF に引き続きモデルを処理させる方法はありますか?

ただし、現在、次のようにモデルを変更すると、機能します

Invoices
-> InvoiceID (Primary, Auto Number)
Orders
-> OrderID (Auto Number)
-> InvoiceID (Primary, FK InvoiceID of Invoices Table)

しかし、これは良い習慣ですか?定義上、Orders テーブルの InvoiceID は確かに一意ですが、比較のためにどこでも OrderID を参照し、他の多くの参照を行うためです。プロパティをインデックス化できることはわかっていますが、このデザインが完璧だとは思いません。

1 対 1 のエラー

4

1 に答える 1

2

ここで明らかな解決策と思われるのは、EDM の Invoice と Order の間の 1:* 関連付けを 1:1 関連付けに変更することです。ただし、経験したように、モデルのように 2 つのエンティティ間に 外部キー アソシエーションがある場合、マッピングは検証されません。

一意の外部キー アソシエーションをマップする唯一の方法は、 独立したアソシエーションを使用することです。これは、外部キーがサポートされていなかった EF3.5 と同じ種類の関連付けです。

外部キー アソシエーションを独立したアソシエーションに変えるには、Order エンティティから InvoiceID 外部キーを削除し、マッピングを通じてアソシエーションを再作成する必要があります。

関連付けを変更するには、次の手順を実行する必要があります。

  1. Order エンティティから InvoiceID 外部キー プロパティを削除します。
  2. 請求書と注文の間の関連付けを選択します。
  3. 関連付けの [プロパティ] ウィンドウで、そのプロパティの横にある省略記号をクリックして参照制約を開きます。
  4. [削除] ボタンをクリックして、制約を削除します。
  5. デザイナで関連付けを右クリックし、コンテキスト メニューから [テーブル マッピング] を選択します。
  6. [マッピングの詳細] ウィンドウで、ドロップダウンを公開する要素。
  7. ドロップダウンから [注文] を選択します。マッピングは自動的に入力されます。
  8. 関連付けの [プロパティ] ウィンドウに戻ります。
  9. 「End2 Multiplicity」というプロパティの値は現在 * Collection of Orders で、ドロップダウン リストを使用してそのプロパティを 1 (One of Order) に変更します。
  10. デザイン サーフェイスを右クリックし、[検証] を選択して、モデルを検証します。このマッピングに関連するエラー メッセージが消えていることがわかります。

アプリケーションでこの問題が発生した場合は、モデルとアプリケーション ロジックにとってどちらが重要かを判断する必要があります。外部キー スカラー (Order.InvoiceID など) と、1 つのエンティティ間の 1:1 関連付けを定義できる機能です。 (Invoice) と別の (Order) は、外部キー (InvoiceID) を介して結合されます。

幸いなことに、新しい EF4.0 の遅延読み込みは引き続き独立した関連付けで動作しますが、外部キーは公開されません。これを取得するには、ナビゲーション プロパティ (Invoice) に移動し、以下のコードのようにその InvoiceID を読み取る必要があります。

Order order = context.Orders.First();
int invoiceID = order.Invoice.InvoiceID;

または、以下のコードを使用して、Invoice プロパティを遅延ロードまたはイーガー ロードすることなく、Order エンティティで直接読み取ることができます。

int invoiceID = order.InvoiceReference.EntityKey.EntityKeyValues[0].Value;
于 2010-11-10T15:01:36.593 に答える