使用代码优先和迁移在两个 class 之间创建 1-1 关系

creating 1-1 relationship between two class using code first and migration

好吧,这是我第一次尝试先使用代码在两个 table 之间创建 1-1 关系。我在网上寻求了一些帮助,并遇到了以下 classes 映射。

比我运行迁移,发现不对。例如。迁移表明 StudentDetails 的主键是来自 Student table 的 Id,而我希望拥有主键 StudentId。此外,正在以相反的方式创建外键。

请有人指出这里有什么问题,或者是我认为错了。

我需要使用 student class 中的 Id 作为 StudentDetails class 中的外键。

public class Student
{
    public bool isPass{get;set;}
    public virtual StudentReport Report { get; set; }
}

public class StudentReport
{
    [Key, ForeignKey("Student")]
    public Guid Id { get; set; }

    public Guid? StudentReportId { get; set; }
    public string RollNumber { get; set; }
    public string StudentType { get; set; }

    public virtual Student Student { get; set; }
}

当我 运行 我的迁移时,我得到以下看起来不太好的结果。

public partial class StudentReport : DbMigration
{
    public override void Up()
{
CreateTable(
    "dbo.StudentReport",
    c => new
    {
    Id = c.Guid(nullable: false, identity: true),
    StudentReportId = c.Guid(),
    RollNumber = c.String(),
    StudentType = c.String(),
    })
    .PrimaryKey(t => t.Id)
    .ForeignKey("dbo.Student", t => t.Id)
    .Index(t => t.Id);
}

在一对一关系中,一端必须是主体,另一端是从属。如果您要在依赖实体中声明 FK 属性,EF 要求 属性 也应该是 PK:

public class Principal
{
   [Key]
   public int Id{get;set;}
   public virtual Dependent Dependent{get;set;}
}

public class Dependent
{
   [Key, ForeignKey("Principal")]
   public int PrincipalId{get;set;}

   public virtual Principal Principal{get;set;}
}

如果你想让两个实体都有自己的 PK,并且还使用 Student 实体中的 Id 作为 StudentReport class 中的 FK,那么你可以尝试使用此模型:

public class Student
{
    [Key]
    public Guid Id { get; set; }
    public bool isPass{get;set;} 
}

public class StudentReport
{
    [Key]
    public Guid StudentReportId{ get; set; }

    [ForeignKey("Student")]
    public Guid StudentId { get; set; }

    public string RollNumber { get; set; }
    public string StudentType { get; set; }

    public virtual Student Student { get; set; }
}

我想您真正需要的是一对多关系,因为一个学生可能有 0 个或多个报告。

检查此 link。它可以帮助您更好地理解如何使用 FK 属性和默认代码优先的名称约定。

更新 1

如果您想创建一对一关系并且两个实体都有自己的 PK,那么由于我在开头解释的限制,您不能在依赖实体中定义 FK 属性我的答案。您需要的解决方案可能是使用 Required 属性并删除 FK 属性:

public class Student
{
    [Key]
    public Guid Id { get; set; }
    public bool isPass{get;set;} 

   public virtual StudentReport StudentReport { get; set; }
}

public class StudentReport
{
    [Key]
    public Guid StudentReportId{ get; set; }

    public string RollNumber { get; set; }
    public string StudentType { get; set; }
    [Required]
    public virtual Student Student { get; set; }
}

更新 2

你确定吗?我得到的迁移代码是这样的:

 AddForeignKey("dbo.StudentReports", "StudentReportId", "dbo.Students", "Id");

这还不行,因为 Code First 仍然按照惯例将 StudentReport 的 PK 配置为 FK。为避免这种情况,您可以将此 Fluent Api 配置添加到您的上下文中:

modelBuilder.Entity<StudentReport>()
            .HasRequired(sr => sr.Student)
            .WithOptional(s => s.StudentReport)
            .Map(c=>c.MapKey("Student_Id"));

这样 Code First 将生成此迁移代码:

 AddColumn("dbo.StudentReports", "Student_Id", c => c.Guid(nullable: false));
 CreateIndex("dbo.StudentReports", "Student_Id");
 AddForeignKey("dbo.StudentReports", "Student_Id", "dbo.Students", "Id");