Raheel Khan
Raheel Khan

Reputation: 14787

Use an auto-generated UNIQUEIDENTIFIER that is NOT a part of the primary key

I have the following EF code-first entity and its corresponding configuration:

public class Category
{
    public virtual long Id { get; set; }
    public Guid Guid { get; set; }
    public string Name { get; set; }
}

public class CategoryConfiguration:
    EntityTypeConfiguration<Category>
{
    public CategoryConfiguration ()
    {
        this.HasKey(entity => entity.Id);
        this.Property(entity => entity.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
        this.Property(entity => entity.Guid).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
    }
}

Setting the DatabaseGeneratedOption.Identity option on the field Guid seems to have no effect and the corresponding table in SQL Server has the IDENTITY option disabled.

Is there a way to have a GUID/UNIQUEIDENTIFIER column in EF that is auto-generated but at the same time NOT part of the primary key?

Upvotes: 0

Views: 2361

Answers (3)

JJJCoder
JJJCoder

Reputation: 16936

For the benefit of searchers using EntityFramworkCore (.NET core), you can do the following:

EF Model (notice default value set on creation)

public class Blog
    {
        public int BlogId { get; set; }
        public string Url { get; set; }

        public Guid BlogGuid { get; set; } = Guid.NewGuid();

        public List<Post> Posts { get; set; }
    }

Create the migration, then change the default to defaultValueSql: "newid()":

public partial class BlogGuidTest : Migration
    {
        protected override void Up(MigrationBuilder migrationBuilder)
        {
            migrationBuilder.AddColumn<Guid>(
                name: "BlogGuid",
                table: "Blogs",
                nullable: false,
                defaultValueSql: "newid()");

            // Add contraint to be safe
            migrationBuilder.AddUniqueConstraint("BlogGuid_Unique", "Blogs", "BlogGuid");
        }

        protected override void Down(MigrationBuilder migrationBuilder)
        {
            migrationBuilder.DropUniqueConstraint("BlogGuid_Unique", "Blogs");

            migrationBuilder.DropColumn(
                name: "BlogGuid",
                table: "Blogs");
        }
    }

Then update the database.

Seems to work ok for me.

Upvotes: 0

tschmit007
tschmit007

Reputation: 7800

a hack...

public calss Guid1 {
    public Guid Guid { get; set; }
}

public class Category {
    public virtual long Id { get; set; }
    public Guid1 Guid { get; set; }
    public string Name { get; set; }
}

public class CategoryConfiguration:EntityTypeConfiguration<Category> {
    public CategoryConfiguration () {
        HasKey(entity => entity.Id);
        Property(x => x.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
        HasReqired(x => x.Guid1);
    }
}

public class Guid1Configuration:EntityTypeConfiguration<Guid1> {
    public Guid1Configuration () {
        HasKey(x => x.Guid);
        Property(x => x.Guid).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
    }
}

this should work but you will get a useless table Guid1.

Upvotes: 0

James
James

Reputation: 82096

EF doesn't "auto-generate" anything related to the ID, that's all handled by the database. Also DatabaseGeneratedOption.Identity isn't tied to the primary key, it's just an indicator to EF that the field value is generated by the DB and therefore should be pulled down.

As long as the default value in the database for your field is set to newid() or newsequentialid() then DatabaseGeneratedOption.Identity should work.

Upvotes: 1

Related Questions