如何通过实体ID判断其为Invoice还是IndividualInvoice类型
解决方案
你当前的场景用的是EF Core默认的TPH(按层次结构分表) 继承映射策略,基类Invoice和派生类IndividualInvoice的数据默认存在同一张表中,EF会自动通过隐式生成的Discriminator字段区分类型,不需要分别查询两个DbSet,比两次调用SingleOrDefault的实现要简洁高效很多。
最简洁实现方案
方案1:仅需要判断类型,不需要返回实体
用AnyAsync直接判断指定ID的实体是否属于IndividualInvoice,仅做计数查询,性能最高:
bool isIndividualInvoice = await context.IndividualInvoices.AnyAsync(i => i.Id == id);
方案2:需要返回实体+区分类型
直接查基类Invoices的DbSet,配合C#模式匹配做类型判断,仅需要1次数据库查询:
[HttpGet("{id}")] public async Task<IActionResult> GetInvoice(string id) { // 主键查询用FindAsync比SingleOrDefault更简洁、性能更高 var invoice = await context.Invoices.FindAsync(id); return invoice switch { null => NotFound(), IndividualInvoice individual => Ok(mapper.Map<IndividualInvoiceDto>(individual)), // 匹配基类逻辑,对应普通企业发票 Invoice companyInvoice => Ok(mapper.Map<InvoiceDto>(companyInvoice)) }; }
方案优势
- 比两次调用
SingleOrDefault的实现少1次数据库请求,性能提升明显 - 代码逻辑更简洁,用C#原生模式匹配做类型判断,可读性更高
FindAsync走EF主键查询优化,支持上下文缓存,重复查询同ID时性能更高
内容的提问来源于stack exchange,提问作者Noah Bergh
相关产品推荐
相关产品推荐

