如何使用 .net 核心实体框架迁移更新表(而不是重新创建它们)
Posted
技术标签:
【中文标题】如何使用 .net 核心实体框架迁移更新表(而不是重新创建它们)【英文标题】:How to update tables (not recreate them) using .net core entity framework migration 【发布时间】:2020-03-09 01:55:40 【问题描述】:我已经连接到一个没有任何身份的现有 SQL 数据库,例如没有 aspNetUser 表等。我已经使用这样的自定义登录类添加了这些
public class UserLogin : IdentityUser
public int LanguageId get; set;
public string HQ_PRM_Id get; set;
然后我生成了一个迁移来创建这样的表(我只是称之为身份)
“dotnet ef 迁移添加身份”
然后我使用
运行迁移“dotnet ef 数据库更新身份”
这创建了表格,一切都很好。但是,我忘记在我添加的用户类中添加名字和姓氏。问题是当我运行我的新迁移时它说
数据库中已经有一个名为“AspNetRoles”的对象。
如何告诉迁移更新架构而不是尝试重新创建表?否则我必须先手动删除对象..这意味着丢失数据。
谢谢
【问题讨论】:
使用新属性更新对象并创建新迁移。这将检测到表已经存在并创建一个只更新现有表的脚本 不幸的是,它没有这样做,生成的迁移代码会识别其他列,但会尝试再次创建表,而不是更新。 您是如何创建第二次迁移的? 和上次一样,使用“dotnet ef migrations add Identity” 您想使用不同的名称创建第二个迁移 【参考方案1】:在开发过程中,模型经常发生变化,并且这些模型(代表数据库表)与表本身不同步。迁移的作用是使数据库和模型保持同步,因此无论何时更改模型,都必须创建新的迁移以增量更新数据库模式。
初始迁移
public class UserLogin : IdentityUser
public int LanguageId get; set;
public string HQ_PRM_Id get; set;
dotnet ef migrations add Identity
- 此命令创建一个名为 Identity 的新迁移
dotnet ef database update Identity
- 此命令运行迁移到并包括一个名为“Identity”的迁移
第二次迁移
public class UserLogin : IdentityUser
public int LanguageId get; set;
public string HQ_PRM_Id get; set;
public string FirstName get; set;
public string LastName get; set;
dotnet ef migrations add AddNames
- 此命令会创建一个名为 AddNames 的新迁移,EF 应该将其识别为对现有表的更新(因此迁移应该只是更新)
dotnet ef database update AddNames
- 这将运行 AddNames 迁移
我绝对建议您查看该主题的 MS docs
【讨论】:
即使添加具有不同名称的新迁移,它仍会尝试重新创建其他表。例如,新的迁移文件只引用了我添加的列,但 ContextModelSnapshot.cs 仍然像往常一样引用其他表。我得到一个没有改变的 aspNetRoles 的“对象已经存在”.. ContextModelSnapshot 类是模型的当前状态。在创建第一个迁移时,该文件将添加到 Migrations 文件夹中,并随着每个后续迁移而更新。它使迁移框架能够计算使数据库与模型保持同步所需的更改。例如,在创建新迁移时,它将检查快照以查看数据库的当前状态,发现表已经存在,并创建更新现有表的迁移。听起来您的 ContextModelSnapshot.cs 正在做它打算做的事情 同样,该信息位于MS Docs 您正在运行什么命令来运行迁移?您是否检查过__EFMigrations
表中针对您的数据库运行了哪些迁移?
所以我的 __EFMigrationsHistory 表显示了以前称为身份的迁移。那是最初的那个。然后我添加了一个列并创建了一个名为 AddPasswordChangeColumn 的迁移。 20191114125408_AddPasswordChangeColumn.cs 文件有 UP 和 Down 方法,Up 方法只添加列,这很好。但是当我对其进行更新时,它仍然会尝试创建另一个自身份迁移以来没有更改的表。以上是关于如何使用 .net 核心实体框架迁移更新表(而不是重新创建它们)的主要内容,如果未能解决你的问题,请参考以下文章