首页 > 解决方案 > Primitive Obsession - 具有自动增量的强类型 int ID

问题描述

如何获得强类型ID...

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

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

...在我的FileUpload课堂上使用...

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... */
}

...使用身份(int自动增量)?

我试过ValueGeneratedOnAdd()我的TypeConifiguration,但没有成功......

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... */
    }
}

我知道HiLo 算法还有另一种选择。但我想让它使用默认的intid 增量。这有可能吗?

标签: c#sql-server.net-coreentity-framework-coredomain-driven-design

解决方案


我设法通过使用.net6和EFCore6获得具有自动递增整数的强类型ID:

  • 配置.HasConversion()
  • 添加.ValueGeneratedOnAdd()
  • 添加.Metadata.SetBeforeSaveBehavior(PropertySaveBehavior.Ignore)
  • 确保强类型 id 永远不会为空

编辑: 这种方法有一个陷阱。

它与更改跟踪有关。由于 ef core 3.0 和这个 GitHub 问题,当您对键使用自动递增且键值不是默认值时,实体会以“已修改”状态而不是“已添加”状态添加。这是当前解决方案的一个问题,因为我们从未为强类型 ID 设置 null。我们必须手动开始跟踪处于“已添加”状态的实体(使用 DbContext Add 方法),其他类型的自动跟踪将不起作用(例如,将实体添加到导航属性集合中以实现一对多关系)。这个 GitHub 问题正在跟踪对此的官方支持。


推荐阅读