Search code examples
c#sqlentity-frameworksql-server-ce

set multiple foreign keys as primary keys in entity framework


I'm using entity framework to manage my sql-server-ce database. i want my table's primary key to be consisted of several foreign keys to other tables. i expected something like this to work:

class Bill{
    [Key]
    public virtual Customer Customer { get; set; }
    [Key]
    public virtual Era Era { get; set; }
    [Key]
    public virtual CompanyCode CompanyCode { get; set; }
    public long? Amount { get; set; }
}

but it results in the following database migration error:

BillPrinter.Bill: : EntityType 'Bill' has no key defined. Define the key for this EntityType. Bills: EntityType: EntitySet 'Bills' is based on type 'Bill' that has no keys defined.

how can i make my table have a primary key consisted of those three foreign keys?


Solution

  • You can't use navigation properties as PKs. Navigation properties provide a way to navigate an association between two entity types but they don't represent by themselves the FK of the relationship. You need to declare explicitly three additional properties to represent the FKs of your relationships, like in this model:

    public class Customer
    {
      public int Id {get;set;}
      //...
    }
    
    public class Era 
    {
      public int Id {get;set;}
      //...
    }
    
    public class CompanyCode 
    {
      public int Id {get;set;}
      //...
    }
    
    
    public class Bill
    {
      [Key] 
      [Column(Order=1)] 
      [ForeignKey("Customer")]
      public int CustomerId {get;set;}
    
      [Key] 
      [Column(Order=2)] 
      [ForeignKey("Era")]
      public int EraId {get;set;}
    
    
      [Key] 
      [Column(Order=3)] 
      [ForeignKey("CompanyCode")]
      public int CompanyCodeId {get;set;}
      //...
      public virtual Customer Customer { get; set; }
      public virtual Era Era { get; set; }
      public virtual CompanyCode CompanyCode { get; set; }
    }
    

    As you can see, when you have composite keys, Entity Framework requires you to define an order of the key properties. You can do this using the Column annotation to specify an order. Also, you need to use the ForeignKey data annotation to clarify your intention which navigation property represents the relationship it is a foreign key for.