实体框架代码首先将TPT转换为TPH

本文关键字:TPT 转换 TPH 框架 代码 实体 | 更新日期: 2023-09-27 18:26:36

我已经开发了一个应用程序(张贴附件,评论等)使用EF代码第一使用TPT。它运行良好,正在与许多客户进行测试。,然而,存在许多层次结构。因此,我有一个包含各种继承模型的基本模型,每个模型都包含许多属性,这些属性本身就是继承类型。

我注意到它非常慢,所以我查看了它正在生成的SQL,为了获得帖子列表,EF正在生成2000多行SQL。编译时间非常长,我不喜欢每次请求都通过有线发送那么多数据的想法。启动时需要5秒才能获得3个帖子。后续的调用要快得多,但每次进行回收时,速度都会再次变慢。

我尝试过Dapper和手写代码,但问题是Dapper不适合需要依赖类型的多级查询;即DisplayTemplates和手工编写的代码,而快速是不合适的,因为它会使未来的开发更加复杂。

我想尝试将一些代码(表)移动到TPH,并认为违反第三规范和代码可维护性之间的权衡是可以接受的,但我找不到任何关于如何转换现有数据库的信息。

如果我从头开始,我只会删除[Table…]注释,但我假设如果我用填充的数据库来做这件事,我将丢失映射表中的所有数据,并且它不会用现有数据填充新的单个表。

这是正确的吗?有人知道如何将现有表从TPT转换为TPH吗。

我只有少数客户将此作为试用版运行,但如果我丢失了他们一半的数据,他们不会高兴的!!

实体框架代码首先将TPT转换为TPH

我不知道有任何工具可以自动从TPT迁移到TPH,但作为DB迁移的一部分,您可以自己迁移数据。

  1. 从类中删除[Table]注释
  2. 使用Add-Migration命令生成新的迁移。生成的迁移将包含成对的AddColumnDropForeignKeyDropIndexDropTable调用
  3. 将所有AddColumn调用放到Up方法的顶部
  4. 编写一个SQL命令,在包含层次结构的所有数据的表中填充新创建的列(不要忘记设置正确的Discriminator)。

    UPDATE [TPHTable]
    SET [TPHTable].[X] = [TPTTable].[X],
        [TPHTable].[Discriminator] = "NameOfTheClass"
    FROM [TPHTable] INNER JOIN [TPTTable]
    ON [TPHTable].[ID] =  [TPTTable].[ID]
    

    迁移允许您调用任意SQL命令,因此在AddColumn方法调用之后将此SQL添加到Up方法中。

    Sql(@"UPDATE [TPHTable] ...");
    
  5. 使用Update-Database命令更新数据库