2013-06-22 10 views
13

のいずれかを用いて構成されている必要があり、「この会合の主要端は、明示的に関係流暢APIまたはデータアノテーションのいずれかを使用して設定する必要があります。」主要端が明示的関係流暢APIまたはデータアノテーション

データベースの更新/移行時にEntity Framework 4.4でこのエラーが発生しましたが、1:1の関係を指定しようとしていません。エンティティAがEntityBが好まエンティティAの子を持つことができるのに対し、EntityBの親を持っている必要がありますが、する必要はありません

public class EntityA 
{ 
    public int ID { get; set; } 
    public int EntityBID { get; set; } 

    [ForeignKey("EntityBID")] 
    public virtual EntityB EntityB { get; set; } 
} 

public class EntityB 
{ 
    public int ID { get; set; } 
    public Nullable<int> PreferredEntityAID { get; set; } 

    [ForeignKey("PreferredEntityAID")] 
    public virtual EntityA PreferredEntityA { get; set; } 
} 

:私はこのような何かをしたいです。優先する子は親に関連付けられた子の1つである必要がありますが、データベースでこれを強制する方法はわかりません。プログラムでそれを強制する予定です。

このエラーを回避するにはどうすればよいですか、これらの関係を達成するためのよりよい方法はありますか?

+1

'[のForeignKey(「EntityAID」) ] 'は、' EntityB.EntityAID'プロパティがあることを意味します。サンプルでそれを見逃しましたか? – Dennis

+1

あなたは[ForeignKey( "PreferredEntityAID")]を意味しますか? – ChaseMedallion

+0

それをキャッチするためにありがとう。私の例でそれを逃した。私はそれを編集した。 – lintmouse

答えて

28

エンティティフレームワークコード - 最初の規則は、EntityA.EntityBEntityB.PreferredEntityAが同じ関係に属し、相互の逆ナビゲーションプロパティであると仮定しています。どちらのナビゲーションプロパティも参照(コレクションではない)であるため、EFは1対1の関係を推論します。

実際には2対1の関係が必要なので、規約をオーバーライドする必要があります。お使いのモデルで、それは流暢APIでのみ可能です:

modelBuilder.Entity<EntityA>() 
    .HasRequired(a => a.EntityB) 
    .WithMany() 
    .HasForeignKey(a => a.EntityBID); 

modelBuilder.Entity<EntityB>() 
    .HasOptional(b => b.PreferredEntityA) 
    .WithMany() 
    .HasForeignKey(b => b.PreferredEntityAID); 

(あなたがこれを使用する場合は、[ForeignKey]属性を削除することができます。)

あなたは、好ましい子供は常にの一つであることを確実にするマッピングを指定することはできません関連する子ども。

あなたがEntityBにコレクションプロパティを追加し、[InverseProperty]属性を使用してEntityA.EntityBにそれを関連付けることができ流暢APIだけデータ注釈を使用しない場合:

public class EntityB 
{ 
    public int ID { get; set; } 
    public Nullable<int> PreferredEntityAID { get; set; } 

    [ForeignKey("PreferredEntityAID")] 
    public virtual EntityA PreferredEntityA { get; set; } 

    [InverseProperty("EntityB")] // <- Navigation property name in EntityA 
    public virtual ICollection<EntityA> EntityAs { get; set; } 
} 
+2

これはそのトリックでした。ありがとう。 – lintmouse