在使用代码和迁移之间创建两个类之间的1-1关系 [英] creating 1-1 relationship between two class using code first and migration

查看:324
本文介绍了在使用代码和迁移之间创建两个类之间的1-1关系的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

嗯,这是我第一次使用代码首先创建两个表之间的1-1关系。我在线上获得了一些帮助,并遇到以下课程映射。



我运行迁移并发现错误。例如。迁移说,StudentDetails的主键是来自Student表的 Id ,而我正在寻找主键StudentId。另外,外键正在以相反的方式创建。



请有人突出显示这里有什么错,或者是我觉得错了。



我需要在StudentDetails类中使用学生类中的 Id 作为外键。

  public class Student 
{
public bool isPass {get; set;}
public虚拟StudentReport报告{get;组; }
}

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

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

public virtual Student Student {get;组;
}

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

  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 ,并且在 StudentReport Id 学生实体作为FK >类,那么你可以尝试这个模型:

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

public class StudentReport
{
[Key]
public Guid StudentReportId {得到;组; }

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

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

public virtual Student Student {get;组;
}

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



查看这个链接。它可以帮助您更好地了解如何使用FK属性和默认代码优先的名称约定。



更新1



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

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

public virtual StudentReport StudentReport {get;组;
}

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

public string RollNumber {get;组; }
public string StudentType {get;组; }
[必需]
public virtual Student Student {get;组;
}



更新2



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

  AddForeignKey(dbo.StudentReports,StudentReportId,dbo.Students , ID); 

哪个还不行,因为Code First仍然按照惯例配置PK $ StudentReport 作为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);


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

解决方案

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

这篇关于在使用代码和迁移之间创建两个类之间的1-1关系的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆