既存(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ファイルがある場合は、単純に開き直せば外部キーが使えるということにはなりません。ひとつひとつのアソシエーションに対して次のような作業が必要になります。
- スカラプロパティCategoryIdを追加し、列マッピングを設定する
- ナビゲーションマッピングから「アソシエーションの選択」で該当のアソシエーションの線(Category)を選択する
- 「参照に対する制約」で「プリンシパル」はそのまま(Category)、「プリンシパルキー」を参照先のプライマリキー(例ではId)、「依存キー」を上で作成した外部キー(例ではCategoryId)として使うプロパティに設定
これを行うことで、無事既存のコードを移行させることが出来そうです。これを画面でやるの他ちょっと手間なので、XMLだけの問題だったら、スクリプトで一括置換すればいいかなと思ったんですが、コードビハインドにもなにやら新しいコードが生成されているようなので、必要なところだけ手でやろうかという気になっています。