Mapping object as identity column in entity framework core

Viewed 496

It is possible map object as identity column with value generated typeof int ? I tried like this but this no help. i've got error

Identity value generation cannot be used for the property 'Id' on entity type 'Article' because the property type is 'ArticleId'. Identity value generation can only be used with signed integer properties.

    public class ArticleId
    {
        public int Value { get; private set; }

        public ArticleId(int value)
        {
            Value = value;
        }
    }

    public class Article 
    {

        public ArticleId Id { get; set; }
        public string Name { get; set; }
    }
     
    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        var converter = new ValueConverter<ArticleId, int>(
                                    v => v.Value,
                                    v => new ArticleId(v)
        );

       modelBuilder
       .Entity<Article>()
       .Property(p => p.Id)     
       .HasConversion(converter)
       .ValueGeneratedOnAdd()
       .UseIdentityColumn();

       base.OnModelCreating(modelBuilder);
    }
2 Answers

Just use this Attribute for the Id property in the Article class:

public class Article
{
    [Column(TypeName = "int IDENTITY(1,1)")]
    public ArticleId Id { get; set; }
    public string Name { get; set; }
}

The migration part will be like this:

protected override void Up(MigrationBuilder migrationBuilder)
{
    migrationBuilder.CreateTable(
        name: "Articles",
        columns: table => new
        {
            Id = table.Column<int>(type: "int IDENTITY(1,1)", nullable: false),
            Name = table.Column<string>(type: "nvarchar(max)", nullable: true)
        },
        constraints: table =>
        {
            table.PrimaryKey("PK_Articles", x => x.Id);
        });
}

And the table in the database is like this: database

No. You cannot use a reference type as a primary key, you'll have to rearchitecture to not have a reference type as a key, however You can make a composite key, so if you take your model and change it to have a primitive type primary key.

Perhaps when squinting at your Article Id, you can allow it doesn't really do anything, so just change it to int ArticleId and it will be key by convention being either called Id og Id

See details: https://docs.microsoft.com/en-us/ef/core/modeling/keys?tabs=data-annotations

Related