简体   繁体   中英

How to create optional constraint in a one to one relationship using Entity Framework Code First

How can I set the ForeignKeys (ideally using Data Annotations) in this scenario:

[Table("Teacher", Schema = "Account")]
public partial class Teacher
{
    [Key]
    public int teacherId { get; set; }

    public string name { get; set; }

    public virtual Address Address { get; set; }
}

[Table("Student", Schema = "Account")]
public partial class Student
{
    [Key]
    public int studentId { get; set; }

    public string name { get; set; }

    public virtual Address Address { get; set; }
}

Both tables Student and Teacher will have one address.

[Table("Address", Schema = "Location")]
public partial class Address
{
    [Key]
    public int addressId { get; set; }

    public string details { get; set; }

    public virtual Student Student { get; set; }

    public virtual Teacher Teacher { get; set; }
}

Table address should have a constraint to either Teacher OR Student tables, meaning that each row in Address table must be linked to either a Student OR a Teacher.

I just cannot find a way to achieve this. With the current code, when adding migration, I got the error: Unable to determine the principal end of an association between the types 'Student' and 'Address'. The principal end of this association must be explicitly configured using either the relationship fluent API or data annotations.

You can achieve this two ways. 1. There is no need to add navigation property on Address class.

[Table("Teacher", Schema = "Account")]
public partial class Teacher
{
    [Key]
    public int teacherId { get; set; }

    public string name { get; set; }

    public virtual Address Address { get; set; }
}

[Table("Student", Schema = "Account")]
public partial class Student
{
    [Key]
    public int studentId { get; set; }

    public string name { get; set; }

    public virtual Address Address { get; set; }
}

[Table("Address", Schema = "Location")]
public partial class Address
{
    [Key]
    public int addressId { get; set; }

    public string details { get; set; }

}

There will be created two relation table Student - Address and Teacher - Address. 2. You can use nullable foreign key property. Like this;

[Table("Address", Schema = "Location")]    
public partial class Address   {

[Key]
public int addressId { get; set; }    
public string details { get; set; }    
public int? teacherId { get; set; }
public int? studentId { get; set; }

[ForeignKey("studentId")]
public virtual Student Student { get; set; }
[ForeignKey("teacherId")]
public virtual Teacher Teacher { get; set; }
}

By the way, if you are interesting to achieve kind of way like this, you may look Inheritance Strategy in Code-First . By using inheritance strategy, you can create a main class and inherit Student and Teacher class from it. After that, use main class id as FK on Address.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM