实体框架 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
中公开,具有外键 DepartmentId
和 Person
类中的导航属性 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的主要内容,如果未能解决你的问题,请参考以下文章