4

I am migrating from .NET EF to EF CORE. I have a working solution that automatically generates a unique GUID aside from its primary key. Below is the solution.

    [Key, Column(Order = 0)]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int Id { get; set; }
    [Index(IsUnique = true)]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public Guid TenantId { get; set; }

However, when i tried to migrate to EF Core, i am getting an error message when inserting the data: >SqlException: Cannot insert the value NULL into column 'TenantId', table 'DBContext.dbo.Tenants'; column does not allow nulls. INSERT fails. The statement has been terminated.

Here's my new code:

    [Key, Column(Order = 0)]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int Id { get; set; }
    public Guid TenantId { get; set; }

Fluent:

    base.OnModelCreating(builder);
    builder.Entity<Tenant>()
     .HasIndex(t => t.TenantId)
     .IsUnique();
    builder.Entity<Tenant>()
     .Property(t => t.TenantId)
     .ValueGeneratedOnAdd();

This is inserted by using:

         _context.Tenants.Add(tenant);
        await _context.SaveChangesAsync();

Is this something that is not supported by EF Core and requires a workaround?

  • How and where is the unique GUID generated? With your setup, EFC expects it to be provided by database (with column `DEFAULT` or something). – Ivan Stoev Nov 07 '17 at 07:29
  • In my .NET Framework version, it is generated automatically by the database. Wouldn't this 'ValueGeneratedOnAdd()' generate it? – pau_learnstocode Nov 07 '17 at 07:39
  • I think you need `HasDefaultValueSql("NEWID()")` instead. – Ivan Stoev Nov 07 '17 at 08:03
  • I tried that also but still has an SqlException cannot insert NULL. – pau_learnstocode Nov 07 '17 at 08:18
  • It has to be applied on table creation or with migration. Otherwise it would not work. The whole idea is that EF sends `NULL` value (or nothing) during the `INSERT` to let column `DEFAULT` clause do the job. If you look at your db table definition, you should see something like `[TenantId] UNIQUEIDENTIFIER DEFAULT (newid()) NOT NULL`. – Ivan Stoev Nov 07 '17 at 08:38
  • 2
    yeah. i needed to recreate the migration for all these to apply. Thanks! – pau_learnstocode Nov 07 '17 at 08:40

2 Answers2

1

On your new code you don't have the [DatabaseGenerated(DatabaseGeneratedOption.Identity)] annotation. Your code should be:

[Key, Column(Order = 0)]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public Guid TenantId { get; set; }
Kostis
  • 953
  • 9
  • 21
  • Isn't it the same with the addition of `builder.Entity() // .Property(t => t.TenantId) // .ValueGeneratedOnAdd();`? I tried that before, it produces the same error. – pau_learnstocode Nov 07 '17 at 07:50
  • ok, so i need to recreate the whole migration from scratch for this changes to reflect in the database. – pau_learnstocode Nov 07 '17 at 08:38
  • I haven't used a guid before as Identity column in EF Core so I can' say for sure..but if you try it give us feedback please :) – Kostis Nov 07 '17 at 08:42
  • 1
    "Identity value generation can only be used with signed integer properties" – liqSTAR Jun 17 '20 at 13:19
-3

I think the reason why you are getting the Null is because you are supposed to instantiate the value of the Guid. something like

[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public Guid TenantId { get; set; } = Guid.NewGuid();
Soji
  • 1