Nathan McKaskle Nathan McKaskle - 1 month ago 17
C# Question

Unable to determine a composite foreign key ordering for foreign key

Person is the user model that includes all users. The change model includes the EngineerId and the ManagerId, both are Person IDs. Why am I getting this error?


Unable to determine a composite foreign key ordering for foreign key on type ProjectName.Models.Change. When using the ForeignKey data annotation on composite foreign key properties ensure order is specified by using the Column data annotation or the fluent API.


public class Change
{
[Key]
public int ChangeId { get; set; }

[Required(ErrorMessage = "Change description is required.")]
[Display(Name = "Change Description")]
[DataType(DataType.MultilineText)]
public string ChangeDescription { get; set; }

[Required(ErrorMessage = "Change date is required.")]
[Display(Name = "Date of Change")]
[DataType(DataType.Date)]
public DateTime ChangeDate { get; set; }

[Required(ErrorMessage = "Time is required.")]
[Display(Name = "Time of Change")]
[DataType(DataType.Time)]
public DateTime ChangeTime { get; set; }

[Required(ErrorMessage = "Engineer name is required.")]
[Display(Name = "Engineer")]
[ForeignKey("person")]
public int EngineerId { get; set; }

[Required(ErrorMessage = "Status is required.")]
[Display(Name = "Status")]
public int StatusId { get; set; }

[Required(ErrorMessage = "Manager is required.")]
[Display(Name = "Manager")]
[ForeignKey("person")]
public int ManagerId { get; set; }

[Required(ErrorMessage = "System is required.")]
[Display(Name = "System")]
public int SystemDetailId { get; set; }

public virtual Person person { get; set; }
public virtual Status status { get; set; }
public virtual SystemDetail systemdetail { get; set; }
}

Answer

You have 2 foreign key properties (EngineerId and ManagerId) that you have associated (via ForeignKey attribute) with the one and the same navigation property (person). This way EF thinks they form a composite key, hence the exception you are getting.

Since (if I understand correctly) your intent is to have 2 relationships, you need to associate each foreign key with a separate navigation property. Here is the essential part that you need to change:

public class Change
{
    // ...

    [Required(ErrorMessage = "Engineer name is required.")]
    [Display(Name = "Engineer")]
    [ForeignKey("Engineer")]
    public int EngineerId { get; set; }

    [Required(ErrorMessage = "Manager is required.")]
    [Display(Name = "Manager")]
    [ForeignKey("Manager")]
    public int ManagerId { get; set; }

    // instead of person property:
    public virtual Person Engineer { get; set; }
    public virtual Person Manager { get; set; }
}
Comments