7

I currently have a class called EmployeeDetails which looks like below.

public class EmployeeDetails {

    public int EmployeeDetailsId { get; set; }
    public string Name { get; set; }
    public string Title { get; set; }

    [ForeignKey("Manager")]
    public int? ManagerId { get; set; }
    public virtual EmployeeDetails Manager { get; set; }
    [ForeignKey("LineManager")]
    public int? LineManagerId { get; set; }
    public virtual EmployeeDetails LineManager { get; set; }

}

I'm trying to add Manager and LineManager properties which will reference objects of the same type. When I try and add a migration I get the following error:

Unable to determine the principal end of an association between the types EmployeeDetails and EmployeeDetails.

The Manager property worked as expected before adding the ManagerId, LineManagerId and LineManager properties.

How can I solve it?

Felipe Oriani
  • 37,948
  • 19
  • 131
  • 194
James
  • 983
  • 1
  • 9
  • 17
  • How does your mapping look like? Do you have a foreign key added on the LineManagerId column? – Herman Cordes Sep 17 '15 at 11:17
  • I don't have any additional mapping attributes on the class at the moment. – James Sep 17 '15 at 11:19
  • You need to map your foreign keys aether using attributes or fluent mappings, your naming conventions don't and can't follow conventions that EF can use to work it out. – Ben Robinson Sep 17 '15 at 11:23
  • I've just added the foreign key attributes as shown in my edit and get the following error: EmployeeDetails_Manager_Target: : Multiplicity is not valid in Role 'EmployeeDetails_Manager_Target' in relationship 'EmployeeDetails_Manager'. Because the Dependent Role properties are not the key properties, the upper bound of the multiplicity of the Dependent Role must be '*'. – James Sep 17 '15 at 11:28
  • You currently have a 1:1 change it to one to many on the fk relationship – g williams Sep 17 '15 at 12:48
  • http://stackoverflow.com/questions/26389707/ef-code-first-one-to-one-relationship-multiplicity-is-not-valid-in-role-in-re – g williams Sep 17 '15 at 13:01

1 Answers1

4

You have to specify the other side of the relationship. Like this:

public class EmployeeDetails
{

    public int EmployeeDetailsId { get; set; }
    public string Name { get; set; }
    public string Title { get; set; }

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

    public virtual EmployeeDetails Manager { get; set; }

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

    public virtual EmployeeDetails LineManager { get; set; }

    [ForeignKey("ManagerId")]
    public virtual ICollection<EmployeeDetails> ManagedEmployees { get; set; }

    [ForeignKey("LineManagerId")]
    public virtual ICollection<EmployeeDetails> LineManagedEmployees { get; set; }

}

Generated Migration

CreateTable(
    "dbo.EmployeeDetails",
    c => new
        {
            EmployeeDetailsId = c.Int(nullable: false, identity: true),
            Name = c.String(),
            Title = c.String(),
            ManagerId = c.Int(),
            LineManagerId = c.Int(),
        })
    .PrimaryKey(t => t.EmployeeDetailsId)
    .ForeignKey("dbo.EmployeeDetails", t => t.LineManagerId)
    .ForeignKey("dbo.EmployeeDetails", t => t.ManagerId)
    .Index(t => t.ManagerId)
    .Index(t => t.LineManagerId);

Does that solve your problem?

Fabio
  • 11,892
  • 1
  • 25
  • 41
  • That does solve my problem. Is there any reference material on how exactly EF determines relations such as these? I'm interested to work why this makes the relationship clearer to EF. – James Sep 17 '15 at 13:57
  • There is the official EF Documentation page https://msdn.microsoft.com/en-us/data/ee712907.aspx#apidocs However, to be honest with you, the documentation is too short, and a lot of features are not mentioned. – Fabio Sep 17 '15 at 14:23