locked
Using [Key] attribute for primary key in code-first w/ Entity-Framework RRS feed

  • Question

  • User-734459410 posted

    If I designate a field with the [Key] attribute in code-first design, can I name the field whatever I want, or does Entity-Framework expect the Primary key field to be called "Id"?

    What I'm looking to create is a table like this (for a photo gallery):

    public class Pictures {
      [Key]
    [Required] public int PictureId;

    [Required]
    [Display(Name = "File URL")]
    public string FileURL;


    [Display(Name = "Caption")]
    public string CaptionText;

    // .. additional fields...
    }

    (I've had issues in the past with database-first and E-F that sometimes, even though a field (such as "PictureId") was defined as a primary key in the database, when I went to add new records with E-F, it would give errors saying there was no primary key defined, despite the field "PictureId" being specified as an auto-increment primary key in the database definition/SQL when the table was created).

    Tuesday, January 9, 2018 9:08 PM

Answers

  • User1400794712 posted

    Hi cbassett,

    cbassett

    If I designate a field with the [Key] attribute in code-first design, can I name the field whatever I want, or does Entity-Framework expect the Primary key field to be called "Id"?

    Yes, code-first doesn't require name of primary key to be "Id", you can define it as what you want. If there is not 'Key' attribute, EF will set the property which is named 'Id' as primary key, then if it doesn't find such a property, it will throw error 'there was no primary key defined'.

    When we use db-first to generate the corresponding model, it won't generate any attribute by default. So, EF can't recognize PictureId as primary key, we should add the Key attribute for this property.

    Any Confusion, please feel free to post back.

    Best Regards,

    Daisy

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Wednesday, January 10, 2018 8:56 AM
  • User1400794712 posted

    Hi cbassett,

    Does it hurt to explicitly tell E-F which column is the key column, even if it's named "Id"?

    Sometimes, I do the same thing, it doesn't make any hurt.

    When we use EF code-first to build many to many tables, we needn't create the model of relationship table. 

    public class Picture
    {
        [Key]
        public int PictureId { get; set; }
        public string PictureName { get; set; }
        public virtual ICollection<Gallery> Gallery { get; set; }
    }
    public class Gallery
    {
        [Key]
        public int GalleryId { get; set; }
        public string GalleryName { get; set; }
        public virtual ICollection<Picture> Picture { get; set; }
    }

    Then after migration, it will generate the Picture_Gallery table automatically.

    Best Regards,

    Daisy

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Friday, January 12, 2018 7:42 AM

All replies

  • User1120430333 posted

    One would think that it would be some kind of binding on the table column name and the property name in the object.

    Tuesday, January 9, 2018 9:22 PM
  • User-734459410 posted

    I will probably do a test design / proof of concept to make sure, with a simplified table to see if it auto-increments without errors.  This was just something I experienced when doing database-first, and someone had said with DB-first, E-F assumes that fields with "Id" are primary keys, and if it can't find a field like "Id" then it thinks there is no primary key.

    Tuesday, January 9, 2018 9:52 PM
  • User1120430333 posted

    I will probably do a test design / proof of concept to make sure, with a simplified table to see if it auto-increments without errors.  This was just something I experienced when doing database-first, and someone had said with DB-first, E-F assumes that fields with "Id" are primary keys, and if it can't find a field like "Id" then it thinks there is no primary key.

    Even after DB first built the edmx, one should still be able to use SSMS, change the PK columnname for the table to something else and go to the edmx file and change it there too to match the table columnname. 

    Wednesday, January 10, 2018 3:15 AM
  • User1400794712 posted

    Hi cbassett,

    cbassett

    If I designate a field with the [Key] attribute in code-first design, can I name the field whatever I want, or does Entity-Framework expect the Primary key field to be called "Id"?

    Yes, code-first doesn't require name of primary key to be "Id", you can define it as what you want. If there is not 'Key' attribute, EF will set the property which is named 'Id' as primary key, then if it doesn't find such a property, it will throw error 'there was no primary key defined'.

    When we use db-first to generate the corresponding model, it won't generate any attribute by default. So, EF can't recognize PictureId as primary key, we should add the Key attribute for this property.

    Any Confusion, please feel free to post back.

    Best Regards,

    Daisy

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Wednesday, January 10, 2018 8:56 AM
  • User-734459410 posted

    OK this makes sense.  Does it hurt to explicitly tell E-F which column is the key column, even if it's named "Id"?  (I went through my model and explicitly defined all of my Keys, even if they are named "Id" in the model.)

    In some tables, which are many to many, I have explicitly also told EF which columns are key columns, as in some cases, I have a composite key consisting of two or more FKs, such as:

    [Table("Pictures_Galleries")]
    public class Picture_Gallery
    {
      [Key, Column(Order = 1)]
      public int PictureId;
    
      [Key, Column(Order = 2)]
      public int GalleryId;
    }
    

    Thursday, January 11, 2018 3:50 AM
  • User1400794712 posted

    Hi cbassett,

    Does it hurt to explicitly tell E-F which column is the key column, even if it's named "Id"?

    Sometimes, I do the same thing, it doesn't make any hurt.

    When we use EF code-first to build many to many tables, we needn't create the model of relationship table. 

    public class Picture
    {
        [Key]
        public int PictureId { get; set; }
        public string PictureName { get; set; }
        public virtual ICollection<Gallery> Gallery { get; set; }
    }
    public class Gallery
    {
        [Key]
        public int GalleryId { get; set; }
        public string GalleryName { get; set; }
        public virtual ICollection<Picture> Picture { get; set; }
    }

    Then after migration, it will generate the Picture_Gallery table automatically.

    Best Regards,

    Daisy

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Friday, January 12, 2018 7:42 AM
  • User-734459410 posted

    That's true.  I do remember in several videos I've watched, that E-F (and in some respects, VS) is somewhat smart in that regard, that it can sometimes figure out which columns should be keys, for example (like one's named "Id", although it may not get it right 100% of the time), among other things.

    (Despite being more work, I do like to ensure that keys and tables are what I expect them to be, as in, I like to define them explicitly, rather than relying on technology to figure it out, but it is nice that E-F is "smart" in some regards, in case you forget, for example, to identify a field named "Id" as a Key column for example.  This probably goes back to my days when programming in C++ and C using things like structures, and my early work with SQL databases where I was simply using SQL queries to communicate with the database: making changes, creating tables, etc.  Obviously, E-F has taken a lot of the hard work out this process.)

    Saturday, January 13, 2018 9:43 PM
  • User1120430333 posted

    Obviously, E-F has taken a lot of the hard work out this process.)

    I am sure DBA(s) around the world are cringing about this. :)

    Sunday, January 14, 2018 2:17 PM