さっそくやってみる

さっそくやたいところなのですが,実はEntity FrameworkではOne to Oneはできないようです.

代わりに,Idに同じIdを使用するShared IDという方式を用いるそうです.

Entity Framework Code First : Setting up One-To-One foreign key association using Annotations

前回同様,プロジェクトを用意し,モデルクラスを定義します.

今回は,OneクラスとThatクラスとします.

One.cs
[csharp]
public class One
{
public int Id { get; set; }
public string Text { get; set; }
public virtual That That { get; set; }
}
[/csharp]

That.cs
[csharp]
public class That
{
public int Id { get; set; }
public string Text { get; set; }
public virtual One One{ get; set; }
}
[/csharp]

Shared IDでは,主キーを共通の値にするため,外部キーを保持しません.

次に,protected override void OnModelCreating(DbModelBuilder modelBuilder)でリレーションシップを定義します.

IdentityModels.cs
[csharp]
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
public ApplicationDbContext()
: base("DefaultConnection")
{
}
public DbSet<One> Some { get; set; }
public DbSet<That> Those { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<One>().HasOptional(o => o.That).WithRequired(t => t.One);
base.OnModelCreating(modelBuilder);
}
}
[/csharp]

OneにオプションとしてThatを持たせ,ThatはOneを必須にします.

つまり,Oneは1つ以下のThatを参照し,Thatは必ず1つのOneを参照します.

relation

これでモデルは完成です.忘れずにマイグレーションしておきます.

PM> Enable-Migrations -EnableAutomaticMigrations
PM> Update-Database

最後に,前回同様,コントローラとビューを自動生成し,サンプルの完成です.

OneのコントローラをSomeController,ThatのコントローラをThoseコントローラとしました.

チェック

ビルドが通ることを確認し,起動してみます.

Oneがない状態でThatを生成することはできないので,Oneから作成します.

addone

Textに文字列をいれCreateボタンで生成します.

Listに戻ると,Oneが追加されています.先頭のTextカラムは関連したThatのTextのことをさしているため,この段階では空欄です.

addedone

次にThatを生成します.Idの指定がドロップダウンリストになっており,Oneのアイテムを選択できます.

addthat

One同様に,Textに文字列をいれCreateボタンで生成します.

Listに戻ると,Thatが追加されています.先ほど選択したOneを参照し,OneのTextもしっかり取得できています.

addedthat

再びSomeリストに戻ると先ほど空欄だったカラムに生成したThatのTextが表示されています.One to Oneになっています.

addedthatone

補足

属性で明示的に[Key]としてしまうとThatの挿入で例外が発生してしまいました.検索してみるとどうやら,IdをIdentity指定にすると代入ができないらしいです.

が,しかし,[Key]をしなくとも,デザイナーで確認するとIdentityやPrimaryKeyが指定されてしまっているので,少し混乱しています.疑問が解けたらまた記事にしたいと思います.

CATEGORIES