Jay
Jay

Reputation: 3082

Entity Framework relationship mapping

I have the following two classes:

public class Department
{
    public int DepartmentID { get; set; }    
    public string Name { get; set; }    
    public int EmployeeCount { get; set; }    
    public int MinimumCoverage { get; set; }        
    public virtual List<Approver> Approvers { get; set; } 
    public virtual List<Employee> Employees { get; set; }
}

public class Employee
{
    public int EmployeeID { get; set; }
    public string Username { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }  
    public int DepartmentID { get; set; }
    public virtual Department Department { get; set; }
    public DateTime StartDate { get; set; }                
    public decimal DaysAccrued { get; set; }
    public decimal DaysUsed { get; set; }
    public decimal DaysRemaining { get; set; }  
    public bool IsManager { get; set; }
    public bool IsApprover { get; set; }
}

I want to have an employee belong to a department using the DepartmentID and in the Department Class have a means of listing all employees in the department but I am getting the following error in my EF set up:

Additional information: Entities in 'HolidayManagerContext.Employees' participate in the 'Employee_Department' relationship. 0 related 'Employee_Department_Target' were found. 1 'Employee_Department_Target'

My context is as follows:

public partial class HolidayManagerContext : DbContext
    {
        public HolidayManagerContext()
            : base("name=HolidayManagerContext")
        {
        }

        public virtual DbSet<Employee> Employees { get; set; }
        public virtual DbSet<Approver> Approvers { get; set; }
        public virtual DbSet<Request> Requests { get; set; }
        public virtual DbSet<Decision> Decisions { get; set; }
        public virtual DbSet<Department> Departments { get; set; }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            modelBuilder.Entity<Employee>()
                .Property(e => e.DaysAccrued)
                .HasPrecision(18, 1);

            modelBuilder.Entity<Employee>()
                .Property(e => e.DaysUsed)
                .HasPrecision(18, 1);

            modelBuilder.Entity<Employee>()
                .Property(e => e.DaysRemaining)
                .HasPrecision(18, 1);

            modelBuilder.Entity<Employee>()
                .HasRequired(e => e.Department)
                .WithMany()
                .WillCascadeOnDelete(false);

        }
    }

Upvotes: 2

Views: 39

Answers (2)

M. Wiśnicki
M. Wiśnicki

Reputation: 6203

Using Code First Data Annotations you can resolve your problem by edit your models, and it should be look like:

public class Department
{
    public Department()
    {
        Approvers = new List<Approver>();
        Employees = new List<Employee>();
    }
    public int DepartmentId { get; set; }
    public string Name { get; set; }
    public int EmployeeCount { get; set; }
    public int MinimumCoverage { get; set; }


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

public class Employee
{

    public int EmployeeId { get; set; }
    public string Username { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public DateTime StartDate { get; set; }
    public decimal DaysAccrued { get; set; }
    public decimal DaysUsed { get; set; }
    public decimal DaysRemaining { get; set; }
    public bool IsManager { get; set; }
    public bool IsApprover { get; set; }

    public int DepartmentId { get; set; }

    [ForeignKey("DepartmentId")]
    public virtual Department Department { get; set; }
}

Without EF conventions you need use ForeignKey attribute on a property where you set FK

 public class Employee
  {
        ...
        public int DepartmentID { get; set; }

        [ForeignKey("DepartmentID")]
        public virtual Department Department { get; set; }
  }

Upvotes: 1

Ivan Stoev
Ivan Stoev

Reputation: 205589

The fluent configuration

modelBuilder.Entity<Employee>()
    .HasRequired(e => e.Department)
    .WithMany()
    .WillCascadeOnDelete(false);

does not match the model navigation properties (1) and the FK field (2), which is causing the issues you are experiencing.

It should be like this:

modelBuilder.Entity<Employee>()
    .HasRequired(e => e.Department)
    .WithMany(d => d.Employees) // (1)
    .HasForeignKey(e => e.DepartmentID) // (2)
    .WillCascadeOnDelete(false);

Note that EF6 default FK name convention is PropertyName_Id (Department_Id in your case).

Upvotes: 2

Related Questions