Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

The property cannot be configured as navigation property

I am trying to implement a domain model like this: My model

This is an entity framework mvc application. The code for the model looks like this:

public class Login
{
    [Key]
    public int LoginID { get; set; }

    public virtual Therapist Therapist { get; set; }

    public virtual Patient Patient { get; set; }
}

public class Patient
{
    [Key]
    [ForeignKey("Login")]
    [Display(Name = "No.")]
    public int PatientId { get; set; }

    [ForeignKey("Therapist")]
    public int TherapistId { get; set; }

    [ForeignKey("Therapist")]
    public int TherapistId{ get; set; }

    public virtual Therapist Therapist { get; set; }

    public virtual Login Login { get; set; }
}

public class Therapist
{
    [Key]
    [ForeignKey("Login")]
    [Display(Name = "No.")]
    public int TherapistId { get; set; }

    [ForeignKey("Login")]
    public int LoginId { get; set; }

    public virtual Login Login { get; set; }

    public virtual ICollection<Patient> Patients { get; set; }
}

I follow exactly what is in the tutorials and stack overflow questions, and no matter what I do, when I try to run the controller, I get the same error:

Unable to retrieve metadata for 'Patient'. The property "TherapistId" cannot be configured as navigation property. The property must be a valid entity type and the property should have non-abstract getter and setter. For collection properties the type must implement ICollection where T is a valid entity type

I have no idea what is wrong with TherapistId - maybe the whole idea of the model is rubbish?

like image 274
Tomek Avatar asked Jun 05 '15 23:06

Tomek


People also ask

What do navigation properties do?

Navigation properties allow you to navigate and manage relationships in both directions, returning either a reference object (if the multiplicity is either one or zero-or-one) or a collection (if the multiplicity is many).

Why is navigation property virtual?

Navigation properties are typically defined as virtual so that they can take advantage of certain Entity Framework functionality such as lazy loading.

Was created in shadow state because a conflicting property with the simple name?

The foreign key property 'InsurancePolicy. InsuranceSubjectID1' was created in shadow state because a conflicting property with the simple name 'InsuranceSubjectID' exists in the entity type, but is either not mapped, is already used for another relationship, or is incompatible with the associated primary key type.


1 Answers

I think your specific error in this case is that you have

[ForeignKey("TherapistId")]
public int? TherapistId { get; set; }

instead of

[ForeignKey("Therapist")]
public int? TherapistId { get; set; }

In any event, you do seem to have a few problems, maybe something like this (I only preserved relationship properties):

public class Login
{
    [Key]
    public int LoginID { get; set; }

    public virtual Therapist Therapist { get; set; }
    public virtual Patient Patient { get; set; }
}

public class Patient
{
    [Key]
    [ForeignKey("Login")]
    [Display(Name = "No.")]
    public int PatientId { get; set; }

    public virtual Login Login { get; set; }

    // was this supposed to be optional?
    [ForeignKey("Therapist")]
    public int? TherapistId{ get; set; }

    public virtual Therapist Therapist { get; set; }
  }

public class Therapist
{
    [Key]
    [ForeignKey("Login")]
    [Display(Name = "No.")]
    public int TherapistId { get; set; }
    public virtual Login Login { get; set; }

    public virtual ICollection<Patient> Patients { get; set; }
}

Usually, for one-to-one relationships in EF, both sides of the relationship must have the same primary key.


In fact, for what you're doing, maybe you could try using inheritance of some sort between Login, Patient, and Therapist, because at the moment, a Login could have both a Patient and Therapist.

like image 115
jjj Avatar answered Sep 18 '22 12:09

jjj