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

时间:2015-12-12 19:54:07

标签: c# entity-framework ef-code-first

我使用TPT使用EF Code First开发了一个应用程序(发布附件,评论等)。它工作正常,并与许多客户进行beta测试。但是有许多层次结构。所以我有一个带有各种继承模型的基础模型,每个模型都包含许多本身都是继承类型的属性。

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

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

我想尝试将一些代码(表)移动到TPH,并考虑在违反第三个规范和代码可维护性之间进行权衡,但我无法找到有关如何转换现有数据库的任何信息

如果我从头开始,我会删除[Table ...]注释,但是我假设如果我用填充的数据库执行此操作,我将丢失映射表中的所有数据,它不会使用现有数据填充新的单个表。

这是对的吗?是否有人知道如何或最佳实践将现有表从TPT转换为TPH。

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

1 个答案:

答案 0 :(得分:4)

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

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

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

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

    Sql(@"UPDATE [TPHTable] ...");
    
  7. 使用Update-Database命令

  8. 更新数据库