EF Core 单表无TPH继承实现求助:ASP.NET Core中规避鉴别器并适配多模式与插件重写场景
EF Core 单表无TPH继承实现求助:ASP.NET Core中规避鉴别器并适配多模式与插件重写场景
我现在在ASP.NET Core项目里用EF Core,想实现无鉴别器(Discriminator)的继承映射,但遇到了一堆坑,想请教下大家怎么解决。先把我的场景和问题说清楚:
一、我的实体与应用架构
1. 实体层级结构
- 🔴 Red(基础类,非抽象):包含通用属性,比如
FirstName、LastName这类所有模式都要用的字段 - ⚫ Black(外部系统扩展类):当应用依赖外部ERP系统时使用,继承自Red,增加ERP相关的专属属性
- 🟢 Green(客户定制扩展类):作为插件层的实体,总是继承自Red或Black,是最底层的具体实现类
2. 应用运行模式与服务重写逻辑
我的应用有两种运行模式:独立模式(用Red实体)、外部系统依赖模式(用Black实体)。同时支持插件重写:
- 非插件的核心控制器(比如用
UserManager/SignInManager的身份验证控制器)默认用Red基础实体 - 服务层分为独立模式服务、外部系统服务,插件服务可以重写这些基础服务——插件服务总是继承自基础层的服务,从上到下逐层覆盖
- 核心诉求:未被重写的服务方法,继续用上层的基础实体;只有被重写的部分,才使用最底层的Green实体。整个应用永远只会有一个最底层的具体实体,查询父类时,子类的额外属性返回null完全没问题,我们的逻辑不依赖这些属性。
二、当前遇到的核心问题
EF Core默认的TPH(表每层次)映射会自动生成Discriminator字段,这直接打乱了我的SQL生成逻辑:
- 未被重写的方法用的是父类的DbContext,不会带新的
Discriminator条件,导致查询出错 - 被重写的方法用的是子类实体,EF会自动加
Discriminator过滤,和未重写部分的查询逻辑冲突 - 整个应用永远只有一个具体实体,完全不需要
Discriminator来区分不同子类,但EF硬要生成这个字段,反而搞乱了查询
三、我已经尝试过的方案及踩的坑
1. 改成抽象类+TPC映射
我把Red改成抽象类,想用TPC(表每具体类)来避免生成Discriminator,但问题来了:身份验证控制器里的UserManager/SignInManager不能用抽象类,直接报错,这条路走不通。
2. 用entity.HasNoDiscriminator()+忽略旧类型
我在OnModelCreating里配置entity.HasNoDiscriminator(),并尝试忽略父类,但结果是未被重写的服务方法直接抛出“找不到旧类型注册”的异常,因为基础服务还是依赖父类实体的DbSet。
3. 重写DbSet
这是之前ChatGPT给的建议,代码如下:
public override DbSet<BaseEntities.Order> Orders => Set<NewOrder>();
听起来很美好,但实际用的时候会出现类型转换错误——父类DbSet和子类实体的类型不兼容,没法正常工作。
四、我需要的解决方案
我想实现的是:
- 完全去掉EF Core自动生成的
Discriminator字段 - 支持非抽象的基础类(因为要在
UserManager/SignInManager里用) - 未被重写的服务方法,能正常用上层实体查询;被重写的方法用底层实体查询,且不会因为
Discriminator导致SQL冲突 - 整个应用永远只有一个具体实体,查询父类时子类属性返回null即可,不需要任何过滤条件
有没有大佬遇到过类似的场景?求指点怎么配置EF Core才能满足我的需求!
内容来源于stack exchange
相关产品推荐
相关产品推荐

