Entity Framework Core(简称 EF Core)是新式应用程序体系结构的实体框架再生成。 由于根本性的变化,没有直接的升级路径。 本文档的目的是提供将 EF6 应用程序移植到 EF Core 的端到端指南。
重要
启动移植过程前,务必验证 EF Core 符合应用程序的数据访问要求。 可以在 EF Core 文档中找到所需的所全部内容。
重要
可移植性分析器存在一个已知问题 (https://github.com/microsoft/dotnet-apiport/issues/993),该问题错误地报告 EF Core 与 .NET 5 和 .NET 6 不兼容。 可以安全地忽略这些警告,因为 EF Core 与 .NET 5 和 .NET 6 目标框架 100% 兼容。
升级原因
所有新的实体框架开发都在 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 角色 | 迁移 | 基架 | 存储库 |
---|---|---|---|---|---|
Code First | 设计实体并验证/自定义生成的迁移 | 验证架构定义和更改 | 按提交 | 空值 | 跟踪实体、DbContext 和迁移 |
Database First | 更改后进行反向工程并验证生成的实体 | 当数据库更改为重新构建基架时,通知开发人员 | 空值 | 按架构更改 | 跟踪扩展生成的实体的扩展/分部类 |
混合 | 更新要在实体或数据库发生更改时映射的流畅配置 | 在数据库发生更改时通知开发人员,以便他们可以更新实体和模型配置 | 空值 | 空值 | 跟踪实体和 DbContext |
与传统的代码和数据库方法相比,混合方法是一种更高级的方法,有额外的开销。
了解远离 EDMX 的影响
EF6 支持名为实体数据模型 XML (EDMX) 的特殊模型定义格式。 EDMX 文件包含多个定义,包括总体架构定义 (CSDL)、映射规范 (MSL) 和存储架构定义 (SSDL)。 EF Core 通过内部模型图形跟踪域、映射和数据库架构,并且不支持 EDMX 格式。 许多博客文章错误地指出这意味着 EF Core 仅支持“代码优先”。EF Core 支持上一部分中所述的所有三种应用模型。 可通过 对数据库进行反向工程在 EF Core 中重新生成模型。 如果你将 EDMX 用于实体模型的可视化表示形式,请考虑使用开源 EF Core Power Tools,为 EF Core 提供类似的功能。
有关缺少对 EDMX 文件支持的影响的详细信息,请阅读移植 EDMX 指南。
执行升级步骤
这不是移植整个应用程序的必要条件。 EF6 和 EF Core 可以在同一应用程序中运行(请查看文末扩展)。 若要将风险降至最低,你可以考虑:
- 如果尚未执行此操作,请转到 .NET Core 上的 EF6。
- 将应用的一小部分迁移到 EF Core,并与 EF6 并行运行。
- 最终将代码库的其余部分带入 EF Core 并停用 EF6 代码。
对于移植本身,从较高层次来看,你需要:
- 查看 EF6 和 EF Core 之间的行为变更。
- 在 EF6 中执行最终迁移(如果有)。
- 创建 EF Core 项目。
- 将代码复制到新项目、运行反向工程或二者的组合。
- 重命名引用、实体和更新行为:
System.Data.Entity
至Microsoft.EntityFrameworkCore
- 改变
DbContext
构造函数以使用选项和/或重写OnConfiguring
DbModelBuilder
至ModelBuilder
- 将
DbEntityEntry<T>
重命名为EntityEntry<T>
- 从
Database.Log
移动到Microsoft.Extensions.Logging
(高级)或DbContextOptionsBuilder.LogTo
(简单) API - 应用对
WithRequired
和WithOptional
的更改 - 更新验证代码。 EF Core 中未内置数据验证,但可以 自己进行数据验证。
- 按照所有必要的步骤从 EDMX 移植。
- 根据 EF Core 方法执行具体步骤:
扩展
在同一个应用程序中使用 EF Core 和 EF6
通过安装这两个 NuGet 包,可在同一应用程序或库中使用 EF Core 和 EF6。
某些类型在 EF Core 和 EF6 中具有相同的名称,并且仅命名空间有所不同,这可能会使在同一代码文件中同时使用 EF Core 和 EF6 变得复杂。 可通过命名空间别名指令轻松消除多义性。 例如:
using Microsoft.EntityFrameworkCore; // use DbContext for EF Core
using EF6 = System.Data.Entity; // use EF6.DbContext for the EF6 version
如果要迁移具有多个 EF 模型的现有应用程序,则可以将其中一些选择性地迁移到 EF Core,其余程序则继续使用 EF6。