我应该如何编写转换数据的实体框架迁移(最好使用 DbContext)?

Posted

技术标签:

【中文标题】我应该如何编写转换数据的实体框架迁移(最好使用 DbContext)?【英文标题】:How should I write an Entity Framework migration that transforms data (preferably using the DbContext)? 【发布时间】:2012-09-17 14:18:48 【问题描述】:

假设我的对象有一个 Name 字段,我希望将其拆分为 FirstName 和 LastName 字段。或者它有一个地址字符串,我正在添加需要地理编码的 Lat 和 Lng 字段。等等等等。

我希望能够在 Up() 和 Down() 方法中访问我的 DbContext,但我所能找到的(除了内置函数)是 .Sql() 调用。这足以添加和删除列,但不足以将现有数据转换为新格式。

在 Up() 调用中引用我的 DbContext 是否安全?或者是否有另一种推荐的模式来实现需要不只是简单 SQL 的迁移?

【问题讨论】:

【参考方案1】:

不,您不能在Up 方法中使用DbContext,因为它已经引用了新模型,但您的数据库仍以旧模型为目标。

编辑:

所有数据迁移必须通过Sql 完成。例如,您可以创建临时表,将旧数据移动到临时表,使用表结构迁移并将数据从临时表移回原始表,直接在 SQL 中使用一些转换 - 拆分 varchar 值应该不是什么大问题。

【讨论】:

我需要的转换不能作为 SQL 完成(拆分 varchars 是一个非常简单的例子)。这种迁移操作在 ActiveRecord 这样的鸭式 ORM 中非常自然,但这是有道理的,这是 EF 方法会遇到麻烦的领域。【参考方案2】:

与其尝试将名称拆分为两个不同的字段,不如重新考虑您的迁移。有时它可能是最好的上演。我可以想到两种方法来执行您的转换。

迁移路径 #1:新字段,然后删除旧字段

    为 FirstName 和 LastName 的新字段创建迁移,在 Up() 方法中,您仍然拥有 Name 字段,将其拆分,插入 First 和 Last 字段。 创建另一个迁移以删除旧的名称字段。

迁移路径 #2:重新调整用途和重命名

    创建迁移,添加 LastName 字段,并将 Name 重命名为 FirstName,移动姓氏数据,修改重命名的 First/Name 字段以仅保留名字。

这两种路径各有利弊。而且,无论您的转换有多复杂,您都应该能够将其分解为符合逻辑的阶段以实现目标。

【讨论】:

以上是关于我应该如何编写转换数据的实体框架迁移(最好使用 DbContext)?的主要内容,如果未能解决你的问题,请参考以下文章

我应该如何迁移我的核心数据?

如何实现 IDbContextFactory 以用于实体框架数据迁移

如何在实体框架数据库迁移中创建全文目录? [复制]

我应该如何设置我的集成测试以使用带有实体框架的测试数据库?

实体框架迁移 API

在不使用其他项目的情况下添加实体框架核心迁移