Full error:

One or more validation errors were detected during model generation:

EFEmployee_Identity_Source: : Multiplicity is not valid in Role 'EFEmployee_Identity_Source' in relationship 'EFEmployee_Identity'. Because the Dependent Role properties are not the key properties, the upper bound of the multiplicity of the Dependent Role must be '*'.

I am dealing with three types of entities: EFEmployee, EFPerson, and EFOffice. It's kind of weird that I'm getting this error because the code I'm testing only creates an instance of an EFOffice entity. Anyway, here is the EFEmployee entity class:

[Table("employee_entity")]
public class EFEmployee : EFBusinessEntity
{
    [ForeignKey("Office")]
    public Guid OfficeID { get; set; }

    [ForeignKey("Identity")]
    public Guid PersonID { get; set; }

    [Column("hire_date")]
    public DateTime HireDate { get; set; }

    [Column("job_title")]
    public byte[] JobTitle { get; set; }

    [Column("salary")]
    public int Salary { get; set; }

    [Column("certifications")]
    public byte[] Certifications { get; set; }

    [Column("vacation_time")]
    public int VacationTime { get; set; }

    [Column("sick_time")]
    public int SickTime { get; set; }

    public virtual EFOffice Office { get; set; }

    public EFPerson Identity { get; set; }

    public virtual EFEmployee ReportingTo { get; set; }
}

And this is my EFPerson entity class:

[Table("person_entity")]
public class EFPerson : EFBusinessEntity
{
    [Column("first_name")]
    [StringLength(50)]
    public string FirstName { get; set; }

    [Column("last_name")]
    [StringLength(50)]
    public string LastName { get; set; }

    [Column("phone_num")]
    public uint? PhoneNum { get; set; }

    [Column("date_of_birth")]
    public DateTime DateOfBirth { get; set; }

    public EFEmployee Employee { get; set; }
}

You can see that they both inherit from EFBusinessEntity, which is here:

[Table("business_entity")]
public abstract class EFBusinessEntity : IBusinessEntity
{
    [Column("tenant_id")]
    public Guid TenantId
    {
        get;
        set;
    }

    [Column("id")]
    [Key]
    public Guid Id
    {
        get;
        set;      
    }
}

As you can see, there is a one-to-zero-or-one relationship between EFEmployee and EFPerson, with EFEmployee being the dependent side since there can be a person who is not an employee, but there can't be an employee who is not a person too. Since EFEmployee is the dependent side, I have added a PersonID in EFEmployee with the data annotation (attribute?) above denoting that it's the foreign key to Person:

[ForeignKey("Identity")]
public Guid PersonID { get; set; }

I think I've made it pretty clear for Entity Framework that this is a 1:0..1 relationship. Does anyone know how to solve this error using data annotations (or attributes, whatever those square bracket things above properties are). I can't use fluent API for reasons I'm not getting into.

2

There are 2 best solutions below

2
On BEST ANSWER

I did some more playing around with the models and found out what was wrong. So I kept the foreign key attribute with EFPerson.Identity like jjj suggested:

[ForeignKey("PersonID")]
public virtual EFPerson Identity { get; set; }

Then the other change I had to make was in the EFPerson class. In my EFPerson class I had the navigation property to EFEmployee:

public virtual EFEmployee Employee { get; set; }

However, since this is a 1:0..1 relationship with EFEmployee being the dependent side (i.e. the non-essential side), I removed that navigation property, and when I ran my test it worked.

5
On

Generally, with 1:0..1 relationships in Entity Framework, the dependent side needs to use its primary key as the foreign key. Fortunately, for your case, this doesn't seem like it would be a bad idea. You would need to:

  1. Remove the EFEmployee.PersonID property
  2. Add [ForeignKey("Id")] to EFEmployee.Identity

Edit: May not work because key and navigation property are on separate classes. See this.

Having EFEmployee inherit from EFPerson seems like it might be a viable option as well. Inheritance uses TPH by default, but if you want to use TPT (table-per-type), add the [Table] attribute to your type.