This my entity:
public class Audit
{
public string Pk { get; set; }
public string TableName { get; set; }
public string RowPk { get; set; }
public string ActionType { get; set; }
public string RowContent { get; set; }
}
This my mapping:
modelBuilder.Entity<Audit>(entity =>
{
entity.HasKey(e => e.Pk).IsClustered(true);
entity.Property(e => e.Pk)
.ValueGeneratedOnAdd()
.UseIdentityColumn()
.HasConversion(new ValueConverter<string, long>(v => Convert.ToInt64(v),v => Convert.ToString(v)));
entity.Property(e => e.TableName).IsRequired().HasMaxLength(255);
entity.Property(e => e.RowPk).IsRequired().HasMaxLength(100);
entity.Property(e => e.ActionType).IsRequired().HasMaxLength(1);
entity.Property(e => e.RowContent).IsRequired;
});
My requirements:
Audit.Pk: string
Pk column: BigInt
and AutoIncrement
Adding the migration I get the following error:
Identity value generation cannot be used for the property 'Pk' on entity type 'Audit' because the property type is 'string'. Identity value generation can only be used with signed integer properties.
Any workaround?
Personally speaking, the string
is not a common data type for primary key
. most of the time we use int
or GUID
. for solving your problem you can use below snippet:
public class Audit
{
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; } //instead of Pk
[NotMapped]
public string Pk => Id.ToString();
.
.
.
}
And finally, Remove all related code to Pk
property from your mapping
Keeping a bigint primary key is easier to maintain for your SQL tables. Otherwise, change your primary key PK
to something like a GUID.
Otherwise, I advise the following change to your class is having a PkString is mandatory in your program (this change is transparent to your database) :
public class Audit
{
[Key]
public long Pk { get; set; }
[NotMapped]
public string PkString => Pk.ToString();
public string TableName { get; set; }
public string RowPk { get; set; }
public string ActionType { get; set; }
public string RowContent { get; set; }
}