4

I have an issue in regards to creating a database from code first in entity framework. I have the following three classes 1 Person, 2 PersonAddress, 3 PersonEmploymentHistory as shown below.

namespace DataAccess.Models
{
[Table("Profile")]
public class Person
{
    [Key]
    public int UserId { get; set; }

    [Required(ErrorMessage = "Firstname is required")]
    public string PersonFirstName { get; set; }

    [Required(ErrorMessage = "Surname is required")]
    public string PersonSurname { get; set; }

    [Required(ErrorMessage = "Email is required")]
    [DataType(DataType.EmailAddress)]
    public string PersonEmail { get; set; }
    public int Age { get; set; }

    [Required(ErrorMessage = "Contact Number required")]
    public Int64 PersonNumber { get; set; }

    public bool IsActive { get; set; }

    [ForeignKey("AddressDetails")]
    public int AddressId { get; set; }
    public virtual PersonAddress AddressDetails { get; set; }

    [ForeignKey("EmploymentHistory")]
    public int EmployerId { get; set; }
    public virtual PersonEmploymentHistory EmploymentHistory { get; set; }

}
}

PersonAddress Class

namespace DataAccess.Models
{
[Table("AddressDetails")]
public class PersonAddress
{
    [Key]
    public int AddressId { get; set; }

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

    [Required(ErrorMessage = "Address Line 1 required")]
    public string AddressLine1 { get; set; }

    [Required(ErrorMessage = "Address Line 2 required")]
    public string AddressLine2 { get; set; }

    [Required(ErrorMessage = "Postcode required")]
    [DataType(DataType.PostalCode)]
    public string PostCode { get; set; }
}
}

PersonEmploymentHistory

namespace DataAccess.Models
{
[Table("EmploymentHistory")]
public class PersonEmploymentHistory
{
    [Key]
    public int EmployerId { get; set; }
    public string EmployerName { get; set; }
    public decimal EmployeeSalary { get; set; }
    public DateTime StartDate { get; set; }
    public DateTime EndDate { get; set; }
    public string ReasonForLeaving { get; set; }

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

And this is my Context class

 public class Context : DbContext
{
    public Context()
        : base("DefaultConnection")
    {
        Database.SetInitializer<Context>(new CreateDatabaseIfNotExists<Context>());
    }

    public DbSet<Person> Person { get; set; }
    public DbSet<PersonAddress> PersonAddress { get; set; }
    public DbSet<PersonEmploymentHistory> PersonEmployment { get; set; }

}

Now I have followed tutorials when creating foreign keys etc but when I run my project and try to insert data into the person table I get the following error

The property 'UserId' cannot be configured as a navigation property. The property must be a valid entity type and the property should have a non-abstract getter and setter. For collection properties the type must implement ICollection where T is a valid entity type.

Jonathan Hall
  • 75,165
  • 16
  • 143
  • 189
Code Ratchet
  • 5,758
  • 18
  • 77
  • 141

4 Answers4

17

I am learning code first also. I am using the fluent API so I am not as experienced with annotations. I think the way you are doing your foreign keys is wrong. I think they should look like:

public int UserId { get; set; }
[ForeignKey("UserId")]
public virtual Person User{ get; set; }

The difference is you have an variable of the type for the FK and annotate that. You can also look up the fluent API.

see http://www.codeproject.com/Articles/319366/EF-Code-First-Add-a-Foreign-Key-relationship

NDC
  • 531
  • 4
  • 11
1

I have had the same problem when developing and relating several tables, if you use FirstCode, I recommend using the following structure:

In Class "PersonAddress"

   public long UserId{ get; set; }
   [ForeignKey("UserId")]
   public Person Person { get; set; }

For the table where you relate use the foreign key pointing or below the object.

Not used that:

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

you will do the same with the other tables that you are going to relate.

-1
[ForeignKey("UserId")]
public virtual Person User{ get; set; }

[ForeignKey("User")]
public int UserId { get; set; }

you should use it like this. I also have the same problem I have solved this problem like this.

Bilal Ch
  • 1
  • 2
-2

In the ForeignKey you need to add the class reference. Change to:

[ForeignKey("Person")]
public int UserId { get; set; }
public virtual Person User{ get; set; }