Richie Mackay
Richie Mackay

Reputation: 1465

Defining a composite key and identity on the same table using EF Code First

Take the following C# code. I am attempting to create ClassC which has a composite key but also create an identity in there that can be used as a foreign key in another table ClassD. I'd rather use this foreign key instead of trying to map the composite key which seems a bit odd.

public class ClassA
{
    [Key]
    public int ClassAID { get; set; }
    public virtual ICollection<ClassC> SomeClassCs { get; set; }
}

public class ClassB
{
    [Key]
    public int ClassBID { get; set; }
    public virtual ICollection<ClassC> SomeClassCs { get; set; }
}

public class ClassC
{
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int ClassCID { get; set; }

    [Key, Column(Order=0), ForeignKey("SomeA")]
    public int ClassAID { get; set; } //Foreign Keys combined as Primary Key

    [Key, Column(Order=1), ForeignKey("SomeB")]
    public int ClassBID { get; set; }

    public virtual ClassA SomeA { get; set; }
    public virtual ClassB SomeB { get; set; }

}

public class ClassD
{
    [Key]
    public int ClassDID { get; set; }

    [ForeignKey("SomeC")]
    public int ClassCID { get; set; }
    public virtual ClassC SomeC { get; set; }
}

On creating my migration I receive the following error:

System.Data.Entity.Edm.EdmAssociationConstraint: : The number of properties in the Dependent and Principal Roles in a relationship constraint must be identical.

Anyone solved this, or am I approaching this incorrectly?

Upvotes: 0

Views: 1441

Answers (2)

Colin
Colin

Reputation: 22595

"I'd rather use this foreign key instead of trying to map the composite key which seems a bit odd"

You are talking about Natural vs Surrogate keys

This is what I do:

  1. Use identity (surrogate) keys on all my models
  2. Validate the data by overriding ValidateEntity in the context class - prevent duplicates in entity framework
  3. Add unique indexes to the natural keys - create indexes in migrations

Entity Framework does not provide data annotation attributes for identifying properties that are natural keys or should have unique indexes - but if you look at the answers in the links I've provided you will see that some people create custom attributes for that purpose

Upvotes: 1

Sergey Berezovskiy
Sergey Berezovskiy

Reputation: 236268

Foreign key of Dependent entity should contain all Primary keys of the Principal. You can read more about foreign key constraints on TechNet.

You have two primary keys on ClassC so, you should have two foreign keys on ClassD for this relation. Or you can make ClassCID to be single primary key, then your mapping for ClassD foreign key will work. In any case - foreign key of dependent table should be exactly same as primary key in principal table.

Upvotes: 0

Related Questions