首页 > 解决方案 > 如何将 DbSet.Find() 与具有抽象类作为键的实体一起使用?

问题描述

我有一个TaxNumber由两种类型实现的抽象类型: CPFCNPJ.

TaxNumber在基本模型中用作主键Person,它也是一个抽象类型,由两种类型实现:PhysicalPersonLegalPerson.

知道:

什么时候,Person是。PhysicalPersonTaxNumberCPF

什么时候,Person是。LegalPersonTaxNumberCNPJ

问题是当我运行DbContext.Persons.Find(CPF)DbContext.Persons.Find(CNPJ). 引发以下异常:

System.ArgumentException: '调用'DbSet .Find'的位置0处的键值是'CPF'类型,与属性类型'TaxNumber'不匹配。

显然,传递给的值Find()必须是 type TaxNumber,但是TaxNumber是抽象类型,不能实例化,Find()在这种情况下如何使用?

为了更好地观看:

public abstract Person 
{
    [Key]
    public TaxNumber TaxNumber { get; set; }
}

public abstract LegalPerson : Person
{
}

public abstract PhysicalPerson : Person
{
}

定义了以下配置:

modelBuilder.Entity<LegalPerson>()
    .Property(v => v.TaxNumber)
    .HasConversion(
        v => v.Unformatted,
        v => v == null ? null : new CNPJ(v));

modelBuilder.Entity<PhysicalPerson>()
    .Property(v => v.TaxNumber)
    .HasConversion(
        v => v.Unformatted,
        v => v == null ? null : new CPF(v));

标签: c#entity-framework-coreef-code-firstasp.net-core-3.1

解决方案


尝试将值转换为基本类型:

DbContext.Persons.Find((TaxNumber)CPF)
DbContext.Persons.Find((TaxNumber)CNPJ)

更新:

或者尝试将值声明为基本类型:

TaxNumber key = CPF;
DbContext.Persons.Find(key);

更新 2:

尝试使用原始类型作为键。

EF Core 支持使用任何原始类型的属性作为主键,包括stringGuidbyte[]

参考:键类型和值


推荐阅读