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)]
Set the default sql value of the field to 'newsequentialid()' in the mapping configuration.
If using .Net core then this should work for you ...
Use fluent API
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Node>().Property(x => x.ID).HasDefaultValueSql("NEWID()");
}
or
modelBuilder.Entity<Student>().Property(p => p.StudentID)
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
Here is a more comprehensive Cheat Sheet for entity framework
You can also set Default Value of ID as NewID() in Sql Server itself and pass the GUID as null
I used to do it in SSMS.
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.
I prefer to leave the database to generate the id automatically for example the following schema:
CREATE TABLE [dbo].[MyTable](
[MyId] [uniqueidentifier] NOT NULL CONSTRAINT [DF_Booking_BookingId] DEFAULT (newsequentialid())
)
Then in the code first mapping I specify the following to tell Entity Framework that the database will take care of generating the value on insert.
Property(a => a.MyId).IsRequired().HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
Just decorate the Id field on your EmailTemplate class as below and SQL Server will automatically generate the value on insert.
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
[Key]
public Guid Id { get; set; }
You can also remove your Mapper class as it's no longer needed.