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

∥☆過路亽.° 提交于 2019-12-25 07:00:13

问题


Well, it is 1st time i am trying to create 1-1 relationship between two tables using code first. I took some help online and come across the following classes mapping.

Than I ran migration and found something wrong. E.g. The migration says that primary key for StudentDetails is Id from Student table whereas I am looking to have primary key StudentId. Also, the foreign key is being created in opposite way.

Please can someone highlight what is wrong here or is it me who perceived it wrong.

I need to use Id from student class as Foreign key in 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; }
}

When i run my migration, i get the following outcome which looks not good.

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);
}

回答1:


In an one to one relationship one end must be the principal and the another one is the dependent. If you are going to declare a FK property in the dependent entity, EF requires that property should be PK too:

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;}
}

If you want to have both entities with their own PKs, and also use Id from Student entity as FK in StudentReport class, then you can try with this model:

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; }
}

I guess what you really need is an one to many relationship because an student could have 0 or many reports.

Check this link. It could help you understand better how to use the FK properties and the name conventions that have by default Code First.

Update 1

If you want to create an one to one relationship and both entities have their owns PKs, then you can't define a FK property in the dependent entity due to the restriction I explain at the begin of my answer. A solution for what you need could be using the Required attribute and deleting the FK property:

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; }
}

Update 2

Are you sure? The migration code that I get is this:

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

Which is not ok yet because Code First is still configuring by convention the PK of StudentReport as FK. To avoid that you can add this Fluent Api configuration to your context:

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

This way Code First will generate this migration code:

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


来源:https://stackoverflow.com/questions/31636987/creating-1-1-relationship-between-two-class-using-code-first-and-migration

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!