2016-02-20 122 views
0

許多和自我引用我有以下關係的兩個實體(這些實體採取唯一的例子的目的)一個在實體框架

public class Entity 
{ 
    public long ID { get; set; } 
} 

public class Doctor : Entity 
{ 
    public string Name {get; set;} 
    public string sprcialization { get; set;} 
    public string Icollection<JrDoctor> childDoctors { get; set;} 
} 

public class JrDoctor : Entity 
{ 
    public long? DoctorId { get; set;} 
    public virtual Doctor Doctor { get; set;} 

    public long? JuniorDoctorId { get; set;} 
    [ForeignKey("JuniorDoctorId")] 
    public virtual Doctor JuniorDoctor { get; set;} 
} 

中的EntityFramework這種關係是建立在JrDoctor表一個額外的列Doctor_Id。爲什麼這樣?以及如何使用數據註釋來避免它。

+0

「Doctor」實體中的關鍵是什麼?關於'JrDoctor'實體的同樣問題? –

+0

@SergeyBerezovskiy ID是這兩個表中的關鍵字,更新了問題 – DivideByzero

回答

0

以下是EF如何工作 - 如果它看到導航屬性(您的情況爲Doctor),那麼EF理解這兩個實體之間是相互關聯的。數據庫中的關係由外鍵定義。因此EF生成名稱爲PropertyName_KeyColumnOfRelatedEntity的外鍵。這就是爲什麼你在JrDoctor表中看到第Doctor_Id列。

如果你不想要默認生成的外鍵列,那麼你應該告訴EF它應該使用什麼。這是通過data annotations屬性或fluent configuration完成的。我更喜歡後者:

modelBuilder.Entity<JrDoctor>() 
    .HasOptional(jd => jd.Doctor) 
    .WithMany(d => d.childDoctors) 
    .HasForeignKey(jd => jd.DoctorId); // here you tell which column is FK 

數據註釋需要修改實體類。在你的情況,你應該添加的屬性,它告訴FK的名字導航屬性,就像你爲JuniorDoctor

public class JrDoctor : Entity 
{ 
    public long? DoctorId { get; set;} 
    [ForeignKey("DoctorId")] 
    public virtual Doctor Doctor { get; set;} 

    public long? JuniorDoctorId { get; set;} 
    [ForeignKey("JuniorDoctorId")] 
    public virtual Doctor JuniorDoctor { get; set;} 
} 
+0

感謝您的解釋。我嘗試用ForiegnKey裝飾Doctor Navigation屬性,但是如果仍然在JrDoctor表中生成Doctor_Id列。我覺得這與一對多關係有關,如果可能爲維持一對多關係創造了額外的關鍵。我可以在Doctor類的collection屬性上使用InverseProperty嗎? – DivideByzero

+0

@zeroCool確保數據庫被刪除,並用您的新模型重新創建:Database.SetInitializer(新的DropCreateDatabaseIfModelChanges ())' –

+0

Berezovsky是的我在運行之前手動刪除數據庫 – DivideByzero

0

InverseProperty的伎倆。

public class Entity 
{ 
    public long ID { get; set; } 
} 

public class Doctor : Entity 
{ 
    public string Name {get; set;} 
    public string sprcialization { get; set;} 
    [InverseProperty("Doctor")] 
    public string Icollection<JrDoctor> childDoctors { get; set;} 
} 

public class JrDoctor : Entity 
{ 
    public long? DoctorId { get; set;} 
    [ForeignKey("DoctorId")] 
    public virtual Doctor Doctor { get; set;} 

    public long? JuniorDoctorId { get; set;} 
    [ForeignKey("JuniorDoctorId")] 
    public virtual Doctor JuniorDoctor { get; set;} 
}