17

I've seen many posts and answers regarding how to mark a field as the identity column. Many of them are outdated and are targeting older versions of Entity Framework.

Some resources tell me to use an attribute on the field:

[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int ID { get; set; }

Other resources tell me to add this code to OnModelCreating method:

modelBuilder.Entity<User>().Property(u => u.ID).HasDatabaseGeneratedOption(System.ComponentModel.DataAnnotations.Schema.DatabaseGeneratedOption.Identity);

Which one should I use? First, second, both, doesn't matter, or something else?

Can Poyrazoğlu
  • 33,241
  • 48
  • 191
  • 389
  • Either, your choice. I use a mixture of the two: attributes for simple things like this, and the `modelBuilder` for more complex scenarios the attributes don't cover. They're both equally valid, and you'll see that under the covers (EF 'conventions'), the attributes are used to tell the `modelBuilder` what to do. –  Nov 26 '15 at 20:06
  • @Amy thank you. I think I'll take the attribute approach as it yields cleaner code. Could you please post your comment as an answer so I can accept it? – Can Poyrazoğlu Nov 26 '15 at 20:07
  • Is this property a primary key? – CodeNotFound Nov 26 '15 at 20:07
  • @CodeNotFound yes. I also have the `Key` attribute (I don't think I need it anyway as the property name is `ID`) – Can Poyrazoğlu Nov 26 '15 at 20:08
  • 1
    You don't need thoses configurations because ID is primary key and numeric type. My answer below. – CodeNotFound Nov 26 '15 at 20:15

4 Answers4

13

As long as the type of the primary key property is numeric or GUID, Code First will, by convention, automatically configure the key as an identity column.

That means you don't need to have any of the configuration you put in your code to explicity set the property as an identity column because Code First already use covention for that. The data annotation attribute or fluent API configurations you set are useless.

You use those configurations on numeric or GUID type primary key only if you want to disable the identity.

CodeNotFound
  • 22,153
  • 10
  • 68
  • 69
  • Didn't know about that. Nice to see I don't need any of those. – Can Poyrazoğlu Nov 26 '15 at 20:24
  • Adding to @CodeNotFound, Entity Framework Code First can use Convention Over Configuration. The Convention is to name your Identity columns either Id, ID, MyClassNameId or MyClassNameID and Entity Framework will do the hardwork for you ,or you use Configuration where you explicitly specify what you want EF Code First to do with your Model, such as add DataAnnotations and using Fluent API Configuration. And you can mix and match conventions and configurations on the same model. – Julius Depulla Nov 26 '15 at 22:22
7

This is for those who lost more than two hours on this issue.

I made a mistake by marking a column as KEY that later I realize it was not the key, but just a column.

My model had dependencies, so I could not just remove the KEY attribute and let it be. The default Id column never got as identity column at SQL Server, either after generating the corresponding migration and setting: identity as true.

Instead, I had to remove the Dbset from context, remove all references to it and from it in other entities. And generate a migration that drops the table, then fixing the model.. make sure it was OK. And then generating the well done model, plugging in all dependencies back.

It was my mistake on the first hand. So I have no body to blame but myself.

Hope no one come to this situation again, but if do happens, this what I did.

Ramon Gonzalez
  • 401
  • 3
  • 3
1

(for people who search and arrive here) One more thing to note is that EF Core will try to use a value in the ID field on an Insert query even though it is marked as DatabaseGeneratedOption.Identity. I had -1 in my Id field an tried to add a new record and expected EF to ignore my value but instead it passed it to the Insert query and failed with 'Cannot insert explicit value for identity column' It only works when you set the Id field to zero.

Paul McCarthy
  • 818
  • 9
  • 24
0

Either, your choice. I use a mixture of the two: attributes for simple things like this, and the modelBuilder for more complex scenarios the attributes don't cover. They're both equally valid, and you'll see that under the covers (EF 'conventions'), the attributes are used to tell the modelBuilderwhat to do.