I am new to EF so here goes.I have a class which contains the following
public class EmailTemplate
{
public Guid Id { get; set; }
[MaxLength(2000)]
Addressing other answers here
None of these other options seem to work and I've questioned this time and time again with the EF team over on github ...
https://github.com/aspnet/EntityFramework6/issues/762
... for some reason the EF dev team seem to think that this is "working by design" and repeatedly close tickets questioning this "bug".
The EF team explanation
For some reason they seem to think that "generating Guids in SQL is considered not best practice and that to ensure the keys are available immediately we should be generating the keys in the app code".
The issue here of course is that highly populated tables run the risk of you taking further business actions consuming an invalid key.
In my case this could break some extremely complex multi server DTC transactions so I don't believe the advice from MS to be correct, that said EF Core doesn't currently support distributed transactions at all so in a focused context they may have a point.
My answer (which actually works)
In short, I solved this by "manually hacking" the generated migration after generating it ...
EF code first migrations, DB generated guid keys
To quote the other question the answer is as follows:
Generate the migration script as you normally would putting both attributes on the key property like this ...
public class Foo
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public Guid Id { get; set; }
}
... declaratively speaking the entity is now correct.
The migration it will generate will look something like:
CreateTable(
"dbo.Foos",
c => new
{
Id = c.Guid(nullable: false),
...
})
.PrimaryKey(t => t.Id)
...;
... I have not been able to pin down why, but in some situations this will work and in others it won't (run the migration, perform an insert to test).
If it fails, roll the migration back then modify it to read something like ...
CreateTable(
"dbo.Foos",
c => new
{
Id = c.Guid(nullable: false, defaultValueSql: "newid()"),
...
})
.PrimaryKey(t => t.Id)
...;
... the extra code here tells SQL to generate the key as we would expect.
As a rule of thumb I would apply this change all the time for consistency reasons and it means that at a glance your migrations will show you exactly what keys are db generated and of course which ones don't.