Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Primitive Obsession - Strongly typed int ID with auto increment

How to get a strongly typed Id...

public sealed class FileUploadId
{
    public int Value { get; }

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

...which is used within my FileUpload class...

public class FileUpload : EntityBase, IAggregateRoot
{
    private FileUpload() { /* Required by EF */ }

    public FileUpload(string name, string relativePath, FileUploadType type, string contentType, long? size = null)
    {
        /* Guard clauses... */

        Id = new FileUploadId(0);

        /* Other properties... */
    }

    public FileUploadId Id { get; }

    /* Other properties... */
}

...working with identity (int auto increment)?

I tried ValueGeneratedOnAdd()in my TypeConifiguration, but without success...

public class FileUploadTypeConfig : IEntityTypeConfiguration<FileUpload>
{
    public void Configure(EntityTypeBuilder<FileUpload> builder)
    {
        builder.HasKey(x => x.Id);
        builder.Property(x => x.Id).HasConversion(x => x.Value, x => new FileUploadId(x)).ValueGeneratedOnAdd();

        /* Other configurations... */
    }
}

I know there's another option with the HiLo algorithm. But I want to get it work with default int id increment. Is this possible in any way?

like image 537
senz Avatar asked Sep 18 '25 15:09

senz


1 Answers

I managed to get strongly typed ids with auto incrementing ints working with .net6 and EFCore6 by:

  • Configuring .HasConversion()
  • Adding .ValueGeneratedOnAdd()
  • Adding .Metadata.SetBeforeSaveBehavior(PropertySaveBehavior.Ignore)
  • Making sure the strongly typed id is never null

Edit: There is a pitfall with this approach.

It has to do with the change tracking. Since ef core 3.0 and this GitHub issue, when you are using auto incrementing for your key and the key value is not it's default, the entity is added in the 'Modified' state instead of the 'Added' state. This is a problem for the current solution as we never set null for the strongly typed ids. We would have to manually begin tracking the entity in the 'Added' state (with the DbContext Add method) and other types of automatic tracking will not work (for example adding the entity in a navigational property collection for a one-to-many relationship). Official support for this is being tracked with this GitHub issue.

like image 121
zdraffko Avatar answered Sep 20 '25 05:09

zdraffko