Entity Framework 7 data annotation support for [DatabaseGenerated(DatabaseGeneratedOption.Identity)] On a Guid type Primary Key

entity-framework-core

Question

I have an entity base class which I use for the basis of all my entities:

    public abstract class EntityBase : IEntity
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public Guid Id
    {
        get
        {
            return _id;
        }

        set
        {
            if (_id.Equals(default(Guid)))
                _id = value;

            if (_id.Equals(value))
                return;

            throw new InvalidOperationException("Primary Keys cannot be changed.");
        }
    }
    Guid _id = default(Guid);

    [Timestamp]
    public byte[] RowVersion { get; set; }
}

However is does not appear that [DatabaseGenerated(DatabaseGeneratedOption.Identity)]

has any effect.

The Migration created has in the CreateTable method like the following:

columns: table => new
            {
                Id = table.Column<Guid>(nullable: false),...

this should be:

Id = c.Guid(nullable: false, identity: true),...

is [DatabaseGenerated(DatabaseGeneratedOption.Identity)] no longer supported in entity framework 7? Or am I missing something?

Accepted Answer

[DatabaseGenerated(DatabaseGeneratedOption.Identity)] is supported in EF7.

Due to EF7 targets various database providers the way it is stored in migration has changed. Since not all providers support identity columns, there is no identity parameter. Instead it is stored as a provider specific annotation. Hence you will see following syntax when a column is going to be used as SQL-Server specific IDENTITY column.

     Id = table.Column<int>(nullable: false)
                    .Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn),

The semantic meaning of DatabaseGeneratedOption.Identity is the same as before. Database will generate a value when a new row is added. When targeting SQL-Server, if it is specified on any of the integer type property then EF7 will create Identity column for it. Since IDENTITY cannot specified on non-integer or non-numeric types, for any other type there will not be any such annotation. Though the property still has feature that adding a new row will generate a value.

In your example the property is of Guid type which translate to uniqueidentifier type in SQL-Server. This type cannot be set IDENTITY hence there is no annotation found in generated migration. If you try to add a record without specifying value, database will generate a value for you. If you explicitly set value to the property Id EF7 will use that value and propagate it to database. That would be expected effect of the annotation.



Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Is this KB legal? Yes, learn why
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Is this KB legal? Yes, learn why