2016-02-20 125 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;} 
}