- Java锁的逻辑(结合对象头和ObjectMonitor)
- 还在用饼状图?来瞧瞧这些炫酷的百分比可视化新图形(附代码实现)⛵
- 自动注册实体类到EntityFrameworkCore上下文,并适配ABP及ABPVNext
- 基于Sklearn机器学习代码实战
EF Core支持多种方式处理具有继承关系的表,现在支持 TPH 、 TPC (EF Core 7)、 TPT ,具体的实现方式可以参考 官方文档 和 这篇文章 .
大致总结一下不同的方式的区别: TPH:所有的类型都放在一张表中,使用discriminator字段用以区别不同的类型 TPT:不同的子类型有单独的表存放子类独有的字段,父虚类型也有一张单独的表存放共有的字段。 TPC:不为父虚类新建表,只有子类型有单独的表,并且表内有父类和子类所有的字段.
由于 TPT 两张表的外键关联设计,在进行查询时,会自动进行的JOIN等连表查询操作,因此极限性能不太行。需要经常用查询父类的情况, TPH 就挺好;需要经常查询子类的时候, TPC 就非常适合。按照官方的说法,正常情况 TPH 就已经满足大多数的场景(这也是EF Core的默认设置),性能也是数一数二的,如果遇到了需要经常单独查询子类型的问题,可以优先考虑 TPC ,仅在一些特殊情况下应该考虑 TPT 。哪些是特殊情况?
请查阅官网 这篇文章的详细讨论 以了解三种不同方式对EF Core生成SQL的影响.
我遇到的这么一个场景,有以下特点:
直接使用 TPH 或者使用 TPC 都不是非常满意,而 TPT 提供了一张父类的表存储公共的字段的这种方法,就显得非常适合.
注:TPC不符合数据库范式设计原则,TPH在空字段非常多的情况下也非常不优雅,强迫症可以使用TPT.
如果是空表的话,直接使用EF Migration就可以了,麻烦的已经有既有数据的情况,由于数据表引用的对象从的总表转移到了子类表,因此直接执行的数据库迁移会提示违反了外键约束.
23503: insert or update on table "AD_AnimalCamera_Data" violates foreign key constraint "FK_AD_AnimalCamera_Data_AD_AnimalCamera_Infos_AttachDeviceId"
解决方案:
由于数据量比较大,而且还有继承关系,手动去操作还是麻烦了一些,可以使用SQL查询进行简化;而第二个方案将由EF Core帮我们将数据插入到正确的位置.
将原来的数据库结构复制一份,并设置为开发环境。接下来修改数据库结构,TPH迁移到TPT模式,只需要在每一个子类表上使用 [Table("")] 标记就行了(当然也可以使用FluentAPI)。标记好了之后,使用EF Migration:
add-migration migrateTPT
由于是只有结构的空表,直接操作就可以成功了.
将旧有数据传输到新的数据表中,尤其注意TPH与TPT之间表的在处理继承关系时的不同.
以AttachDeviceInfo为abstract类,AD_Insect_Info作为其中的一个子类 。
更新之后TPH表中的大量字段转移到了子类表中,因此可以使用数据库同步工具进行数据同步,忽略多余的字段就可以了。对于的TPT生成的子类表,通过Id字段与抽象类表进行匹配连接,因此需要手动插入对应类别的数据.
INSERT into "AD_Insect_Infos"
SELECT "Id",FALSE from "AttachDeviceInfos" WHERE "AttachDeviceTypeId" = 1
如果没有 AttachDeviceTypeId 字段,那么需要在TPH阶段先通过 discriminator 将不同子类区分开,这个会麻烦一点.
清空目标数据库(包括结构),并将临时数据库中的表同步到目标数据库中,手动调整_EFMigration表格的记录(指向最新版本),完成切换.
在数据库还是原来结构的情况下,我们需要将现有的数据进行序列化,之前我写过一篇 序列化文章 ,使用的是PROTOBUF序列化。这里由于传输的数据结构比较简单,可以使用System.Text.Json类库Json序列化到文件.
对于有继承关系的表的序列化,.NET 7的System.Text.Json新增了对应的 支持 ,可以参考文档的相关实现.
将原来的数据库结构复制一份,并设置为开发环境。接下来修改数据库结构,TPH迁移到TPT模式,只需要在每一个子类表上使用 [Table("")] 标记就行了(当然也可以使用FluentAPI)。标记好了之后,使用EF Migration:
add-migration migrateTPT
由于是只有结构的空表,直接操作就可以成功了.
由于临时数据库结构已经和既有数据库不同,无法通过程序直接连接两个数据库进行数据导入的操作,因此需要将数据反序列化到的新的数据库.
清空目标数据库(包括结构),并将临时数据库中的表同步到目标数据库中,手动调整_EFMigration表格的记录(指向最新版本),完成切换.
迁移到TPT时,可以使用临时数据库中转,将数据库的数据以新的结构存储下来,然后再同步到新数据库。当然也可以直接在正式数据库中操作:直接持久化,清空数据,然后再还原数据。当然这么风险更高,强调一点,在生产的数据库中进行操作需要格外谨慎,务必做好备份.
可以发现,在数据库中使用外键约束时,虽然给基于导航属性的应用(例如OData)提供了便利,同时将数据完整性检查后置到了数据库中;但是进行架构调整是一件比较麻烦的工作,对分布式应用也非常不友好.
P.S. TPT的查询性能很差,因此绝大多数场景都不推荐,仅在自己完全清楚并权衡了利弊的情况下再使用TPT.
最后此篇关于EFCore从TPH迁移到TPT的文章就讲到这里了,如果你想了解更多关于EFCore从TPH迁移到TPT的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
在我的项目中,我使用 TPT 作为测试环境,我们使用基于模型的测试。代码覆盖率通常在 80% 左右。但是客户要求100%的覆盖率,所以想用.c和.h文件进行测试。 我是这类测试的新手,因为我们只进行了
我首先使用代码,然后使用 TPT 继承。正在生成实体的基本类型表,但其主键上没有标识。 (如果有帮助,我可以发布代码)我的个人表有一个主键,但没有“是身份”。子类表按预期生成。 由于它没有为基本类型生
我正在编写一个使用继承的应用程序,我试图将其映射到具有 TPT 结构的 SQL Server 数据库。 但是,出于某种原因,EF 在父类(super class)表和子类表中生成了重复的外键。 我有这
我在我的数据库中创建了大量的表,以下是有问题的表: Table Name -Item ItemID - PK (Auto Increment) Title Table N
我正在尝试使用 TPT java api 来实现项目的一些自动化。 并尝试使用函数“generateTestCasesFromTestData”“添加步骤列表”但无法弄清楚从哪里获取其第一个参数“Sc
如何确定具有 TPT 继承的实体的子类型? 如果我有一个基类 Person 和两个子类 Manager 和 Customer,应该可以查询所有的人,然后通过使用 GetType 方法按他们的子类分组,
我有一个带有 TPT 继承映射的项目,现在我需要给它添加一个搜索功能,以便在多个表中查找记录。这就是我目前拥有的: public abstract class Customer { publi
我们正在使用 C# MVC .NET4。 EF5(代码优先)。 我们正在尝试构建一个系统,该系统应动态允许用户将额外属性“附加”到任何实体。 假设我们有 ProductClass 和 Products
我的域实体正在使用 EF Table Per Type Inheritance,这是关系。 如您所见,发票位于父实体 Order.cs 上。这让我现在在处理发票时遇到问题。 例如,要创建发票,我需要将
我有这个数据库结构: 服务 Id 整数 PK CategoryId FK 一些其他领域 本地化服务 LocalizedServiceId 公钥 LanguageId FK 姓名 描述 如您所见,我有一
我将 EF 与代码优先和 TPT(每个类型的表)继承结合使用。我有以下模型: public partial class AccountHolder { public int AccountHo
概览 我首先使用实体框架 4.3 代码和流畅的界面来设置我的 DbContext。我有一个基 Item 类,其中包含继承它的其他类型,例如 Event、BlogPost、ForumThread、W
在 Entity Framework 的早期版本中,在使用 Table per Type 继承时存在一些严重的性能问题,如下所述: http://www.codeproject.com/Article
考虑以下具有 TPT 继承的 Entity Framework 模型。 数据库表: Person (PersonID, Name) Student (PersonID, Grade) EF 实体: P
我试图达到的是使用 TPT 继承的 AbstractUser 和 Plant 之间的 NM 关系。 当我尝试配置关系时, modelBuilder.Entity().HasMany(c => c.Re
我们的系统正在接收来自两个外部来源的输入(电话/网络提交)。 // Table-Per-Type Hierarchy public class Submission { public int
我有一个关于 TPT + EF6 的大问题。 在我的数据库模型中,我有一张表 Person(我的应用程序中人员的基本信息),并且我有用于 Supplier 和 Consumer 的表. 我的类(cla
我想在 EF 中实现以下模型作为 TPT 设计。 我的代码如下: 基础型号 public abstract class Product { public int Id { get; set;
这个问题会围绕Account、IndividualAccount、Doctor这3个class进行说明: 前两个类是抽象的 IndividualAccount 是 Account 的子类 Doctor
针对遗留数据库使用 Entity Framework 4.1,我无法生成工作的 TPT 继承模型集,这些模型没有复数化并且对公共(public)主键使用不同的名称。 我正在使用数据库表 Organiz
我是一名优秀的程序员,十分优秀!