这在一定程度上取决于您想要实现的表结构类型。有多种方法可以做到这一点,并且所有选项都有一个很好的演练,从这些链接中的共享主键关联到一对一外键关联。不幸的是,这些链接比 Annotations 更多地使用 Fluent。下面的示例根据需要使用注释。
共享主键
理论上共享主键(水平表分区,在数据库术语中)是“正确的方法”。这也是生成迁移所需的最小更改(将使用共享主键关联)。请注意,我将更改为Person.Id
以Person.UserId
更好地显示您的意图:
// tested in EF 5 and MVC 4.5.
[Table("UserProfile")]
public class UserProfile {
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int UserId { get; set; }
public string UserName { get; set; }
}
[Table("Person")] // not required, added for clarity in sample code
public class Person {
// Note the change of property name to reflect that this is a shared primary key,
// using the UserId column in UserProfile as the Primary Key
[Key]
public int UserId { get; set; }
[ForeignKey("UserId")]
public virtual UserProfile UserProfile { get; set; }
}
// The generated migration:
public partial class AddTable_Person : DbMigration
{
public override void Up() {
CreateTable(
"dbo.Person",
c => new {
UserId = c.Int(nullable: false),
})
.PrimaryKey(t => t.UserId)
.ForeignKey("dbo.UserProfile", t => t.UserId)
.Index(t => t.UserId);
}
public override void Down(){
DropIndex("dbo.Person", new[] { "UserId" });
DropForeignKey("dbo.Person", "UserId", "dbo.UserProfile");
DropTable("dbo.Person");
}
}
这实际上为您提供了(这是强制性的)和(这是可选的,但每个人最多可以有一个1:0-1
关系)之间的关系。UserProfile
People
如果您想使用Id
,Person
请执行以下操作(迁移将相应更改):
public class Person {
public int Id { get; set; }
[ForeignKey("Id")]
public UserProfile UserProfile { get; set; }
}
双向导航的共享主键
如果您想从 导航到UserProfile
,Person
您还有更多工作要做。简单地添加public virtual Person Person { get; set; }
到 UserProfile 会给你一个错误:
无法确定类型“Test.Models.UserProfile”和“Test.Models.Person”之间关联的主体端。此关联的主体端必须使用关系流式 API 或数据注释显式配置。
因此,我们使用[Required]
属性Person.UserProfile
( Person
requires UserProfile
) 修复它。这给出了与以前相同的迁移。
// tested in EF 5 and MVC 4.5.
[Table("UserProfile")]
public class UserProfile {
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int UserId { get; set; }
public string UserName { get; set; }
[ForeignKey("UserId")]
public virtual Person Person { get; set; }
}
[Table("Person")] // not required, added for clarity in sample code
public class Person {
[Key]
public int UserId { get; set; }
[ForeignKey("UserId")]
[Required]
public virtual UserProfile UserProfile { get; set; }
}
同样,如果您使用Id
forPerson
而不是UserId
:
public class Person {
[Key]
public int Id { get; set; }
[ForeignKey("Id")]
[Required]
public virtual UserProfile UserProfile { get; set; }
}