既存(v3.5 時代)のモデルにおけるアソシエーションを外部キーアソシエーションへ変更する方法

Entity Framework v1で外部キーによるリレーションは、アソシエーションとしてマッピングされていました。

こんなテーブルで、Products.CategoryIdがCategories.Idを参照しているとします。これを1.0で自動生成すると、アソシエーションが作られ、こんな感じになります(複数形を手で単数形に直した)

このやりかただと、Productには、CategoryIdというキーそのものはなくなり、代わりにCategoryのインスタンスそのものを参照できるようにアソシエーションが作られます。これはこれで思想としてはすっきりしています。ただ、実際にアプリケーションを作っていると、どうしてもCategoryId自体を参照したくなることがあります。これをv1でやろうとすると、EntityKeyから

(long)_product.CategoryReference.EntityKey.EntityKeyValues.First().Value;

みたいなことをやる必要がありました。めんどうです。

これに対して、Entity Framework v4では、外部キーであるCategoryIdを残したままアソシーエションを張れるようになるということでした。

さっそく4になって、既存のコードを移行させるべく試してみたのですが、既存のアソシエーションに自動的にスカラプロパティが定義されるのかと思いきや、どうやらそうではないようです。そもそも、外部キーを残したままのアソシエーションと、v1流の外部キーを残さないアソシエーションとでは、そもそも意味合いが異なるようなのです。前者(v4で採用された、外部キーを参照できるタイプのもの)を「外部キーアソシエーション」といい、後者(v1で使われていた旧来のもの)を「独立アソシエーション」と呼ぶようです(http://msdn.microsoft.com/ja-jp/library/ee373856.aspx を参照)。

というわけで、既存のEDMファイルがある場合は、単純に開き直せば外部キーが使えるということにはなりません。ひとつひとつのアソシエーションに対して次のような作業が必要になります。

  1. スカラプロパティCategoryIdを追加し、列マッピングを設定する

  1. ナビゲーションマッピングから「アソシエーションの選択」で該当のアソシエーションの線(Category)を選択する
  2. 「参照に対する制約」で「プリンシパル」はそのまま(Category)、「プリンシパルキー」を参照先のプライマリキー(例ではId)、「依存キー」を上で作成した外部キー(例ではCategoryId)として使うプロパティに設定

  1. アソシエーションの線を選択し、「マッピングの詳細」タブをクリック。「マッピングを削除する」を選択する


これを行うことで、無事既存のコードを移行させることが出来そうです。これを画面でやるの他ちょっと手間なので、XMLだけの問題だったら、スクリプトで一括置換すればいいかなと思ったんですが、コードビハインドにもなにやら新しいコードが生成されているようなので、必要なところだけ手でやろうかという気になっています。