c# - 如何将 DbSet.Find() 与具有抽象类作为键的实体一起使用?
问题描述
我有一个TaxNumber
由两种类型实现的抽象类型:
CPF
和CNPJ
.
TaxNumber
在基本模型中用作主键Person
,它也是一个抽象类型,由两种类型实现:PhysicalPerson
和LegalPerson
.
知道:
什么时候,Person
是。PhysicalPerson
TaxNumber
CPF
什么时候,Person
是。LegalPerson
TaxNumber
CNPJ
问题是当我运行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));
解决方案
尝试将值转换为基本类型:
DbContext.Persons.Find((TaxNumber)CPF)
DbContext.Persons.Find((TaxNumber)CNPJ)
更新:
或者尝试将值声明为基本类型:
TaxNumber key = CPF;
DbContext.Persons.Find(key);
更新 2:
尝试使用原始类型作为键。
EF Core 支持使用任何原始类型的属性作为主键,包括
string
、Guid
等byte[]
参考:键类型和值
推荐阅读
- php - 关于 PHP 中的 elvis 运算符的困惑
- c# - 创建 ac# 统计服务的线程安全版本
- aem - AEM Workflow 自定义输入数据
- node.js - 如何在 Node.js 中记录可点击的文件目录
- python - 导入 face_recognition ImportError:在 mod_wsgi 中没有名为 face_recognition 的模块
- java - 用 Spring 返回一个空的 ResponseEntity 的最佳方法是什么?
- java - Android XzingScanner:如何自定义 ZxingScanner 布局?(添加按钮)
- qt - 如何忽略 Qt 中的 PressAndHold 事件?
- r - 在 data.table 构造函数中使用字符串作为列名
- android - 自动布局所有设备 sw 布局文件夹