user3953989 user3953989 - 6 months ago 196
SQL Question

EF6 how to map this zero or one to one relationship

This is Code-First.

What's the correct Fluent or data annotation for this relationship?

Getting EF mapping error:
Unable to determine the principal end of an association between the types 'Model.SchoolInfo' and 'Model.School'. The principal end of this association must be explicitly configured using either the relationship fluent API or data annotations.

If I add

modelBuilder.Entity<School>().HasOptional(s => s.SchoolInfo).WithRequired(ss => ss.School);


I get this error:
One or more validation errors were detected during model generation: School_SchoolInfo_Target: : Multiplicity is not valid in Role 'School_SchoolInfo_Target' in relationship 'School_SchoolInfo'. Because the Dependent Role properties are not the key properties, the upper bound of the multiplicity of the Dependent Role must be '*'.

SQL Tables

table School
(
int SchoolId not null PK
)

table SchoolInfo
(
int SchoolInfoId not null PK IDENTITY
int SchoolId not null FK UNIQUE
)


Models

class School
{
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
int schoolId;

virtual SchoolInfo SchoolInfo;
}

class SchoolInfo
{
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
int schoolInfoId;

int schoolId;

virtual School School
}

Answer

If you want to implement 1:1 mapping, this is how tables should look like:

Schools

SchoolInfoes

And your entity classes in that case would look like this:

public class School
{
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int SchoolId { get; set; }

    public virtual SchoolInfo SchoolInfo { get; set; }
}

public class SchoolInfo
{
    [ForeignKey("School")]
    public int SchoolInfoId { get; set; }

    public virtual School School { get; set; }
}

Your current table structure suggests 1:M mapping, and in order to map entity classes to it, you need to do slight changes:

public class School
{
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int SchoolId;

    public virtual IList<SchoolInfo> SchoolInfoes { get; set; }
}

public class SchoolInfo
{
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int SchoolInfoId { get; set; }

    public int SchoolId { get; set; }

    public virtual School School { get; set; }
}
Comments