从 EF6 移植到 EF Core

实体框架核心(简称 EF Core)是对新式应用程序体系结构的 Entity Framework 的完全重写。 由于基本更改,没有直接升级路径。 本文档的目的是提供端到端指南,用于将 EF6 应用程序移植到 EF Core。

重要

在开始移植过程之前,请务必验证 EF Core 是否满足应用程序的数据访问要求。 可以在 EF Core 文档中找到所需的一切。

警告

EF Core 仅支持新式 .NET,不支持 .NET Framework。 因此,如果项目仍面向 .NET Framework,则必须迁移到新式 .NET,然后才能开始从 EF6 迁移到 EF Core。 请注意,EF6 支持新式 .NET,因此可以先迁移到新式 .NET,同时保留 EF6,然后处理从 EF6 到 EF Core 的迁移。

升级的原因

所有新的 Entity Framework 开发都在 EF Core 中发生。 没有计划将任何新功能向 EF6 向后移植。 EF Core 在最新的 .NET 运行时上运行,并充分利用运行时、特定于平台(如 ASP.NET Core 或 WPF)和特定于语言的功能。 下面是从升级中获得的一些好处:

  • 请充分利用 EF Core 持续的 性能改进。 例如,由于 查询拆分功能,从 EF6 迁移到 EF Core 6 的一个客户使用大量查询减少了 40 倍。 许多客户只需迁移到最新的 EF Core 即可报告巨大的性能提升。
  • 在 EF Core 中使用 新功能 。 不会向 EF6 添加新功能。 所有新功能,例如 Azure Cosmos DB 提供程序DbContextFactory,仅会添加到 EF Core。 有关 EF6 与 EF Core 的完整比较,包括 EF Core 专属的多项功能,请参阅: 比较 EF Core 和 EF6
  • 使用依赖项注入实现应用程序堆栈的现代化,并将数据访问与 gRPC 和 GraphQL 等技术无缝集成。

有关迁移的说明

本文档使用术语 端口升级 来避免将术语 迁移 作为 EF Core 的一项功能混淆。 由于对迁移的处理方式有显著改进,EF Core 中的 迁移与 EF6 Code First 迁移 不兼容。 没有推荐的方法来移植您的迁移历史,因此计划在 EF Core 中从头开始。 你可以从 EF6 迁移中维护代码库和数据。 在 EF6 中应用最终迁移,然后在 EF Core 中创建初始迁移。 未来,你将能够在 EF Core 中跟踪历史记录。

升级步骤

升级路径已拆分为多个文档,这些文档按升级阶段和应用程序类型进行组织。

确定 EF Core“风格”

有多种策略可用来借助 EF Core 处理您的域模型和数据库实现。 一般情况下,大多数应用将遵循以下模式之一,你处理端口的方式将取决于应用程序“风格”。

代码为事实来源 是一种方法,其中所有内容无论是通过数据属性、流畅配置还是两者结合,均通过代码和类进行建模。 数据库最初基于 EF Core 中定义的模型生成,并且通常通过迁移处理进一步更新。 这通常称为“代码优先”,但名称并不完全准确,因为一种方法是从现有数据库开始,生成实体,然后使用代码继续维护。

数据库作为事实来源的方法涉及反向工程或从数据库搭建代码的基架。 进行架构更改时,将重新生成或更新代码以反映更改。 这通常称为“数据库优先”。

最后,更高级的 混合映射 方法遵循代码和数据库单独管理的理念,EF Core 用于在两者之间映射。 此方法通常避免迁移。

下表汇总了一些高级差异:

方法 开发人员角色 DBA 角色 迁移 脚手架 存储库
代码优先 设计实体并验证/自定义生成的迁移 验证架构定义和更改 按提交 跟踪实体、DbContext 和迁移
数据库优先 在更改后进行逆向工程并验证生成的实体 当数据库更改为重新构建基架时,通知开发人员 按架构更改 跟踪扩展生成的实体的扩展/分部类
混合 更新要在实体或数据库发生更改时映射的流畅配置 在数据库发生更改时通知开发人员,以便他们可以更新实体和模型配置 跟踪实体和 DbContext

与传统代码和数据库方法相比,混合方法是一种更高级的方法,具有额外的开销。

了解远离 EDMX 的影响

EF6 支持名为 Entity Data Model XML(EDMX)的特殊模型定义格式。 EDMX 文件包含多个定义,包括概念架构定义(CSDL)、映射规范(MSL)和存储架构定义(SSDL)。 EF Core 通过内部模型图跟踪域、映射和数据库架构,不支持 EDMX 格式。 许多博客文章和文章错误地指出,这意味着 EF Core 仅支持“代码优先”。EF Core 支持上一部分中介绍的所有三个应用程序模型。 可以通过 反向工程数据库在 EF Core 中重新生成模型。 如果将 EDMX 用于实体模型的可视表示形式,请考虑使用为 EF Core 提供类似功能的开源 EF Core Power Tools

有关对 EDMX 文件缺乏支持的影响的详细信息,请阅读 移植 EDMX 指南。

执行升级步骤

不需要移植整个应用程序。 EF6 和 EF Core 可以在同一应用程序中运行(请参阅: 在同一应用程序中使用 EF Core 和 EF6)。 若要将风险降到最低,可以考虑:

  1. 如果尚未执行此操作,请转到 .NET Core 上的 EF6。
  2. 将应用的一小部分迁移到 EF Core,并并行运行 EF6。
  3. 最终将其余代码库引入 EF Core 并停用 EF6 代码。

对于移植本身,从较高层次来看,你需要:

  1. 查看 EF6 和 EF Core 之间的行为更改
  2. 在 EF6 中执行最终迁移(如果有)。
  3. 创建 EF Core 项目。
  4. 将代码复制到新项目、运行反向工程或两者的组合。
  5. 重命名引用和实体并更新行为:
    • System.Data.EntityMicrosoft.EntityFrameworkCore
    • 改变 DbContext 构造函数以使用选项和/或重写 OnConfiguring
    • DbModelBuilderModelBuilder
    • DbEntityEntry<T> 重命名为 EntityEntry<T>
    • Database.Log迁移到Microsoft.Extensions.Logging(高级)或DbContextOptionsBuilder.LogTo(简单) API
    • 应用对 WithRequiredWithOptional 的更改(请参阅此处
    • 更新验证代码。 EF Core 中没有内置的数据验证,但你可以 自己执行此作
    • 按照所有必要的步骤从 EDMX 移植
  6. 根据 EF Core 方法执行特定步骤:

有许多与所有方法相关的注意事项,因此还需要查看解决以及规避EF6与EF Core之间详细差异的方法。