如何在SQL Server中创建带继承的表?ASP.NET Core IdentityUser扩展
解决方案:ASP.NET Core IdentityUser 派生类的 SQL Server 表实现
首先明确:你用的INHERIT是PostgreSQL的表继承语法,SQL Server并不支持,这是执行失败的核心原因。针对ASP.NET Core中IdentityUser的派生类,SQL Server里常用两种实现方式,以下是具体步骤:
方案1:表每层次继承(TPH,推荐用于Identity场景)
这是EF Core默认的继承映射策略,所有继承层次的类共用一张表(即AspNetUsers),通过自动生成的鉴别器列区分不同类型的用户。
- 定义派生类
public class WebUser : IdentityUser { public string? PoEmail { get; set; } public string? RemEmail { get; set; } public string? HsbEmail { get; set; } public string? GrEmail { get; set; } }
- 配置DbContext
将DbContext的泛型参数指定为WebUser,EF会自动处理继承映射:
public class AppDbContext : IdentityDbContext<WebUser> { public AppDbContext(DbContextOptions<AppDbContext> options) : base(options) { } // 可选:自定义鉴别器列(默认自动生成名为Discriminator的列) protected override void OnModelCreating(ModelBuilder builder) { base.OnModelCreating(builder); builder.Entity<WebUser>() .HasDiscriminator<string>("UserType") .HasValue<WebUser>("WebUser"); } }
- 更新数据库
执行EF Core迁移命令,自动修改AspNetUsers表:
Add-Migration AddWebUserExtraProperties Update-Database
执行后,AspNetUsers表会新增你定义的4个Email字段,以及鉴别器列(如果自定义了的话)。
方案2:表每类型继承(TPT)
每个类对应独立的表,AspNetUsers存储基类属性,WebUsers存储派生类的额外属性,通过外键关联两张表。
定义派生类(同方案1)
配置DbContext
指定派生类映射到单独的表:
public class AppDbContext : IdentityDbContext<WebUser> { public AppDbContext(DbContextOptions<AppDbContext> options) : base(options) { } protected override void OnModelCreating(ModelBuilder builder) { base.OnModelCreating(builder); // 配置TPT映射,将WebUser映射到WebUsers表 builder.Entity<WebUser>().ToTable("WebUsers"); } }
- 更新数据库
执行迁移命令生成新表:
Add-Migration CreateWebUsersTable Update-Database
此时会生成WebUsers表,包含4个Email字段和与AspNetUsers关联的Id外键列。
两种方案对比
- TPH:查询无需联表,性能更好,结构简单,适合大多数Identity用户扩展场景。
- TPT:表结构更清晰,但查询需要联表,性能略低,适合派生类属性较多、且基类被多个派生类继承的复杂场景。
内容的提问来源于stack exchange,提问作者Megan Paterson
相关产品推荐
相关产品推荐

