EntityFrameworkCoreで整数とか日付とか以外のオブジェクトをフィールドに持つクラスをデータベースで管理したいときにやること
やりたいこと
例えば商品(Product)をデータベースで管理したくてかつ商品が会社(Company)の情報を持っていて欲しいとき。
つまりはクラスの入れ子になっているクラスをデータベース管理したいとき。
具体的に書くとこんなの
//商品クラス public class Product { public int ID { get; set; } public Company Maker { get; set; } } //会社クラス public class Company { public string Name { get; set; } public string Location { get; set; } }
できない理由
これをこのままデータベースにマイグレーション(dotnet-ef migrations add hogehoge)しようとしても次のように怒られると思う。
The entity type 'Company' requires a primary key to be defined. // Companyに主キーが無いぞ!出直してこい!!
これはCompanyというクラスを別のテーブルに突っ込んで管理しようとしてるからだ(と思う)が、わざわざそんなことしてくれんでもええのに……となる。
解決方法
要は別のテーブルにではなくProductのテーブルに突っ込んでくれればすむ話である。
EntityFrameworkCoreにはそのように指定する方法があって、次のようにすればよい
using Microsoft.EntityFrameworkCore; public class Product { public int ID { get; set; } public Company Maker { get; set; } } //この属性をつける [Owned] public class Company { public string Name { get; set; } public string Location { get; set; } }
親のテーブルに突っ込みたいクラスに「Owned」という属性をつけているだけである。
これを使うにはNugetとかでMicrosoft.EntityFrameworkCoreを入れておく必要がある。
こうすることによってProductのテーブルに「Maker_Name」とか「Maker_Location」とかのカラムが追加されてそこからMakerが読み取られるようになる。
Makerを別のテーブルに突っ込んでたりもしないので「Companyに主キーが必要だ!」とかも言われずにデータベースを作ることができる。