实体框架 4.1 代码优先外键 ID

Posted

技术标签:

【中文标题】实体框架 4.1 代码优先外键 ID【英文标题】:Entity Framework 4.1 Code First Foreign Key Id's 【发布时间】:2011-08-05 02:20:19 【问题描述】:

我有两个实体被一对多引用。当实体框架创建表时,它会创建两个外键,一个用于我使用 fluent 接口指定的键,另一个用于 ICollection。如何摆脱重复的外键?

public class Person

    public long RecordId  get; set; 
    public string FirstName  get; set; 
    public string LastName  get; set; 
    public string Email  get; set; 
    public string Username  get; set; 

    public long DepartmentId  get; set; 
    public virtual Department Department  get; set; 


public class Department

    public long RecordId  get; set; 
    public string Name  get; set; 

    public virtual ICollection<Person> People  get; set; 


protected override void OnModelCreating(DbModelBuilder modelBuilder)

    modelBuilder.Entity<Person>()
        .HasRequired(p => p.Department)
        .WithMany()
        .HasForeignKey(p => p.DepartmentId)
        .WillCascadeOnDelete(false);

谢谢!

【问题讨论】:

【参考方案1】:

您必须明确指定关联的多端:

modelBuilder.Entity<Person>()
    .HasRequired(p => p.Department)
    .WithMany(d => d.People)
    .HasForeignKey(p => p.DepartmentId)
    .WillCascadeOnDelete(false);

否则 EF 将假定存在两种关联:一种未在 Department 中公开,具有外键 DepartmentIdPerson 类中的导航属性 Department,正如您在 Fluent 代码中定义的那样 -和另一个关联,它属于暴露的导航属性People,但在Person 中有另一个未暴露的结尾,以及由 EF 自动创建的外键。这是您在数据库中看到的另一个键。

【讨论】:

这可行吗? : [ForeignKey("Department")] public long DepartmentId get;放; @billy:这不是 100% 相同,因为注释不会禁用级联删除。如果您不想禁用级联删除,那么它可以工作,是的。但是你甚至不需要注释,因为命名约定会自动检测外键属性。【参考方案2】:

默认的 Code First 约定会检测您的 DepartmentId 外键,因为它是约定俗成的。我认为您应该删除 Fluent 定义:

modelBuilder.Entity<Person>()
    .HasRequired(p => p.Department)
    .WithMany()
    .WillCascadeOnDelete(false);

【讨论】:

【参考方案3】:

最好的办法是从 Person 类中删除 departmentid 属性并添加以下语句。 MapKey 将使用您指定的名称创建外键列

 modelBuilder.Entity<Person>().HasRequired(p =>  p.Department)
    .WithMany().Map(x=>x.MapKey("DepartmentId"))
    .WillCascadeOnDelete(false);

【讨论】:

我尝试了这种方法,但在运行Seed() 方法时导致异常,引用默认列名而不是MapKey() 中指定的列名。

以上是关于实体框架 4.1 代码优先外键 ID的主要内容,如果未能解决你的问题,请参考以下文章

实体框架代码优先空外键

实体框架代码优先:具有两个外键的表

实体框架中与代码优先外键的更改冲突

实体框架代码优先 - 来自同一个表的两个外键

理解实体框架核心外键关系

首次使用实体框架代码时将外键设置为 null