a.k.a How can we create multiple identity columns in Code First?
Because of clustering performance, a common recommendation is to use an autoincremented int
This ended up working for me, Entity Framework 5.
Declare the ClusterId
as Identity (annotation)
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public override int ClusterId { get; set; }
Migrate
Declare the pk property Id
as Identity after the other one has been updated
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public override Guid Id { get; set; }
Id
is primary key, so you don't need [Key, Required]
Create the migration code like add-migration TrickEfIntoAutogeneratingMultipleColumns
Up()
method, in the AlterColumn
statement, tell the database to autogenerate the GUID by declaring the defaultSqlValue
AlterColumn(theTable, "Id", c => c.Guid(nullable: false, identity: true, defaultValueSql: "newid()"));
This seems to "trick" EF, in the sense that it assumes both columns are identities and reacts accordingly. During migration, it tries to make another column an identity, but seemingly doesn't care when that silently fails -- you end up with one marked as Identity and the other with a default value.
During normal code operation, when EF goes through the SaveChanges/ChangeTracking steps, because it sees the Id
property as an Identity it does it's whole "assign temporary key" thing, so that it's not trying to use the default 0000000... value, and instead lets the database generate it using the default value function you specified.
(I would have thought annotating this field as Computed
would have accomplished the same thing, but...the errors I mentioned in the question...boo...)
And, because the ClusterId
field is also an Identity in code, and really is an Identity in the database, it autoincrements as well.