public class Foo
{
public string FooId{get;set;}
public Boo Boo{get;set;}
}
public class Boo
{
public string BooId{get;set;}
public Foo Foo{get;set;}
}
エラーが発生したときに、Entity Frameworkでこれを実行しようとしていました。
タイプ「ConsoleApplication5.Boo」と「ConsoleApplication5.Foo」の間の関連付けの主な終了を判別できません。このアソシエーションのプリンシパルエンドは、リレーションシップの流れるAPIまたはデータアノテーションを使用して明示的に構成する必要があります。
このエラーの解決策についてStackOverflowで質問を見ましたが、「プリンシパルエンド」という用語の意味を理解したいです。
1対1の関係では、一方の端がプリンシパルであり、もう一方の端が依存している必要があります。プリンシパルエンドは、最初に挿入され、依存するエンドなしで存在できるエンドです。依存端は、プリンシパルへの外部キーがあるため、プリンシパルの後に挿入する必要があるものです。
エンティティフレームワークの場合、依存するFKもそのPKである必要があるため、次のように使用する必要があります。
public class Boo
{
[Key, ForeignKey("Foo")]
public string BooId{get;set;}
public Foo Foo{get;set;}
}
または流mappingなマッピング
modelBuilder.Entity<Foo>()
.HasOptional(f => f.Boo)
.WithRequired(s => s.Foo);
これを解決するために [Required]
データ注釈属性を使用することもできます:
public class Foo
{
public string FooId { get; set; }
public Boo Boo { get; set; }
}
public class Boo
{
public string BooId { get; set; }
[Required]
public Foo Foo {get; set; }
}
Foo
にはBoo
が必要です。
これは、1対1の関係を構成するための流れるようなAPIの使用に関する@Ladislav Mrnkaの回答を参照しています。
FK of dependent must be it's PK
を使用することが不可能な状況がありました。
たとえば、Foo
は既にBar
と1対多の関係になっています。
public class Foo {
public Guid FooId;
public virtual ICollection<> Bars;
}
public class Bar {
//PK
public Guid BarId;
//FK to Foo
public Guid FooId;
public virtual Foo Foo;
}
ここで、FooとBarの間にもう1対1の関係を追加する必要がありました。
public class Foo {
public Guid FooId;
public Guid PrimaryBarId;// needs to be removed(from entity),as we specify it in fluent api
public virtual Bar PrimaryBar;
public virtual ICollection<> Bars;
}
public class Bar {
public Guid BarId;
public Guid FooId;
public virtual Foo PrimaryBarOfFoo;
public virtual Foo Foo;
}
Fluent APIを使用して1対1の関係を指定する方法は次のとおりです。
modelBuilder.Entity<Bar>()
.HasOptional(p => p.PrimaryBarOfFoo)
.WithOptionalPrincipal(o => o.PrimaryBar)
.Map(x => x.MapKey("PrimaryBarId"));
PrimaryBarId
の追加中は、流れるようなAPIで指定するため、削除する必要があることに注意してください。
メソッド名[WithOptionalPrincipal()][1]
は皮肉なことに注意してください。この場合、プリンシパルはBarです。 WithOptionalDependent() msdnの説明により、より明確になります。