You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

EF Core中使用UseTpcMappingStrategy()实现各表独立自增ID

问题:使用TPC映射策略时为每个子类表配置独立ID生成机制

我正在编写Code-First数据库项目,使用UseTpcMappingStrategy()从继承类生成数据库表,希望每个子表拥有独立的ID生成机制,而非共享基类的序列。

当前配置代码如下:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.HasDefaultSchema("GAME");

    var armorPrototype = modelBuilder.Entity<ArmorPrototype>();
    armorPrototype.HasBaseType<ItemPrototype>();
    armorPrototype.ToTable("ArmorPrototypes");

    var itemPrototype = modelBuilder.Entity<ItemPrototype>()
        .UseTpcMappingStrategy();

    var weaponPrototype = modelBuilder.Entity<WeaponPrototype>();
    weaponPrototype.HasBaseType<ItemPrototype>();
    weaponPrototype.ToTable("WeaponPrototypes");

    base.OnModelCreating(modelBuilder);
}

生成的迁移代码会创建共享序列:

migrationBuilder.CreateSequence(
            name: "ItemPrototypeSequence",
            schema: "GAME");

migrationBuilder.CreateTable(
            name: "ArmorPrototypes",
            schema: "GAME",
            columns: table => new
            {
                Id = table.Column<decimal>(type: "decimal(20,0)", nullable: false, defaultValueSql: "NEXT VALUE FOR [GAME].[ItemPrototypeSequence]"),
                Name = table.Column<string>(type: "nvarchar(max)", nullable: false),
                Value = table.Column<decimal>(type: "decimal(20,0)", nullable: false),
                IsUsable = table.Column<bool>(type: "bit", nullable: false),
                IsEquippable = table.Column<bool>(type: "bit", nullable: false),
                IsTradable = table.Column<bool>(type: "bit", nullable: false),
                IsUpgradable = table.Column<bool>(type: "bit", nullable: false),
                UpgradeLevel = table.Column<byte>(type: "tinyint", nullable: false),
                RequiredLevel = table.Column<long>(type: "bigint", nullable: false),
                Rarity = table.Column<int>(type: "int", nullable: false),
                DefenseValue = table.Column<long>(type: "bigint", nullable: false),
                EquippableBy = table.Column<string>(type: "nvarchar(max)", nullable: false)
            },
            constraints: table =>
            {
                table.PrimaryKey("PK_ArmorPrototypes", x => x.Id);
            });

请问如何跳过数据库序列,让每个表拥有独立的ID生成机制?同时疑惑使用双列键是否能解决此问题。


解决方案

1. 为每个子类配置独立的ID生成策略

EF Core在TPC模式下默认会给基类创建共享序列,要实现子类独立ID,需要手动覆盖每个子类的ID生成配置,关闭基类的序列绑定,为每个子类指定自己的ID生成方式(比如Identity自增、独立序列等)。

修改你的OnModelCreating方法,按以下方式配置:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.HasDefaultSchema("GAME");

    // 配置基类使用TPC映射,清除默认的序列生成配置
    var itemPrototype = modelBuilder.Entity<ItemPrototype>()
        .UseTpcMappingStrategy();
    itemPrototype.Property(x => x.Id)
        .ValueGeneratedNever();

    // 配置ArmorPrototype的独立ID(使用数据库自增列,每个表独立递增)
    var armorPrototype = modelBuilder.Entity<ArmorPrototype>();
    armorPrototype.HasBaseType<ItemPrototype>();
    armorPrototype.ToTable("ArmorPrototypes");
    armorPrototype.Property(x => x.Id)
        .UseIdentityColumn();

    // 配置WeaponPrototype的独立ID
    var weaponPrototype = modelBuilder.Entity<WeaponPrototype>();
    weaponPrototype.HasBaseType<ItemPrototype>();
    weaponPrototype.ToTable("WeaponPrototypes");
    weaponPrototype.Property(x => x.Id)
        .UseIdentityColumn();

    base.OnModelCreating(modelBuilder);
}

如果不想用Identity自增,而是想用独立序列,也可以为每个子类创建专属序列:

// 为ArmorPrototypes创建独立序列
modelBuilder.HasSequence<decimal>("ArmorPrototypeSequence", "GAME");
armorPrototype.Property(x => x.Id)
    .HasDefaultValueSql("NEXT VALUE FOR [GAME].[ArmorPrototypeSequence]");

// 为WeaponPrototypes创建独立序列
modelBuilder.HasSequence<decimal>("WeaponPrototypeSequence", "GAME");
weaponPrototype.Property(x => x.Id)
    .HasDefaultValueSql("NEXT VALUE FOR [GAME].[WeaponPrototypeSequence]");

2. 关于双列键的疑惑

双列键(复合主键)并不是解决这个问题的正确方案。TPC映射的核心就是每个子类表拥有独立的主键,不需要额外的列来区分。使用双列键反而会增加数据冗余和查询复杂度,完全没必要。你只需要确保每个子类的ID生成逻辑独立即可,不需要修改主键结构。


内容的提问来源于stack exchange,提问作者Sarcovitz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 02:52:46