Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Problem modelling relationship in Entity Framework using code first

I'm trying to learn code first within the Entity Framework and am having trouble modelling a relationship. It's a basic HR database which for the sake of this has two entities, Employees and Departments.

The Employee belongs to a department and the department has a Team Administrator and a Manager, both of whom are in effect employees. I've tried to model this using the following:

EMPLOYEE

public int? DepartmentID { get; set; }
public virtual Department Department { get; set; }

Context:

modelBuilder.Entity<Employee>().HasOptional(x => x.Department);

DEPARTMENT

public class Department
{
    [Required]
    public int DepartmentID { get; set; }

    [Required(ErrorMessage = "The description is required.")]
    public string Description { get; set; }

    public int? ManagerID { get; set; }
    public virtual Employee Manager { get; set; }

    public int? TeamAdministratorID { get; set; }
    public virtual Employee TeamAdministrator { get; set; }
}

Context:

modelBuilder.Entity<Department>().HasOptional(x => x.Manager);
modelBuilder.Entity<Department>().HasOptional(x => x.TeamAdministrator);

Obviously I would want the Department table to have only four columns - DepartmentID, Description, ManagerID and TeamAdministratorID but it is generating an extra two for the relationship, namely Manager_EmployeeID and Team_Administrator_EmployeeID. Also, in the Employee table the column Department_DepartmentID is generated to store the DepartmentID instead of it using the DepartmentID column I specified in the entity.

What am I doing wrong? How do I need to define the fields and relationships to avoid having code first ignore what I specify and generate it's own navigation fields in the database?

like image 900
MC76 Avatar asked Jun 12 '11 12:06

MC76


1 Answers

That because your model configuration is incomplete - you started your own mapping with Fluent API so you must tell EF that these properties are indeed FKs for relations. For employee use:

modelBuilder.Entity<Employee>()
            .HasOptional(x => x.Department)
            .WithMany()
            .HasForeignKey(x => x.DepartmentID);

And for department use:

modelBuilder.Entity<Department>()
            .HasOptional(x => x.Manager)
            .WithMany()
            .HasForeignKey(x => x.ManagerID);
modelBuilder.Entity<Department>()
            .HasOptional(x => x.TeamAdministrator);
            .WithMany()
            .HasForeignKey(x => x.TeamAdministratorID);

Btw. without collection navigation properties on opposite side of relations it will be hard to use model (all WithMany are empty). At least Department should have:

public virtual ICollection<Employee> Employees { get; set;}

And mapping should be modified to:

modelBuilder.Entity<Employee>()
            .HasOptional(x => x.Department)
            .WithMany(y => y.Employees)
            .HasForeignKey(x => x.DepartmentID);
like image 144
Ladislav Mrnka Avatar answered Oct 05 '22 09:10

Ladislav Mrnka