如何使用 .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 核心实体框架迁移更新表(而不是重新创建它们)的主要内容,如果未能解决你的问题,请参考以下文章

实体框架核心更新-数据库特定迁移

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

如何从 DBContext(实体框架核心)中的 App.config(不是 .net 核心应用程序)读取值

如何在实体框架中进行迁移?

实体框架核心中的截断表

如何使实体框架对每条记录使用 1 个更新查询而不是 1 个?