This project is read-only.

codefirst and composite keys

Oct 12, 2011 at 6:05 PM

Another codefirst question... how do I define composite keys?

For example, I have CommunicationTemplate, Language and CommunicationTemplateTranslation.  What I'd like is for CommunicationTemplateTranslation to have a composite key, identified by (communication_template, language).  However:

public class CommunicationTemplateTranslation    {
        [Key]
        [Column(Name="CommunicationTemplate_Code", Order=0)]
        public virtual CommunicationTemplate Template { get; set; }

        [Key]
        [Column(Name="Language_Code", Order=0)]
        public virtual Language Language { get; set; }

        ...
}

as per http://sankarsan.wordpress.com/2011/06/05/entity-framework-4-1-annotationspart-1/ does not seem to map:

[ModelValidationException: One or more validation errors were detected during model generation:

	System.Data.Edm.EdmEntityType: : EntityType 'CommunicationTemplateTranslation' has no key defined. Define the key for this EntityType.
	System.Data.Edm.EdmEntitySet: EntityType: EntitySet �CommunicationTemplateTranslations� is based on type �CommunicationTemplateTranslation� that has no keys defined.
]

It looks like this [Key] and [Column] information is not being passed through to EF?

Thx
Dan

Oct 12, 2011 at 6:23 PM

I think (from memory) that Naked Objects running Code First can cope with compound keys, but they would need to be integer keys.  I'm guessing that the error you're getting is because you don't have any integer key rather than because you've got more than one key.  However, it ought to be possible to make this work, because EF can cope with the idea of an association having both an object property and a foreign key property  -  and you can change the associated object by setting either one.  In that case I can't see why you couldn't use one of those FK properties as also being a primary key:

public class CommunicationTemplateTranslation    {

        [Key, Hidden]
        public virtual int TemplateId { get; set; }

        public virtual CommunicationTemplate Template { get; set; }

        [Key, Hidden]
      public virtual int LanguageId { get; set; }

        public virtual Language Language { get; set; }

        ...
}

BTW  -  I think the convention is that the FK property has to be the same name as the object property with the suffix 'Id'  -  but I'm doing that from (vague) memory.  Check that up  with an online search if it doesn't work.

Oct 12, 2011 at 10:09 PM

For EF questions that are not specific to Naked Objects, I suggest posting to the EF Forum, where all the EF experts are.