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

如何通过实体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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 21:27:01