如何在ASP.NET Core中拆分数据表并迁移指定数据?
在ASP.NET Core(EF Core)中实现数据表拆分与数据迁移
1. 定义实体类
先创建TableB实体,同时修改TableA实体,添加外键并移除原字段:
// TableB.cs public class TableB { public int Id { get; set; } public string Colb1 { get; set; } public string Colb2 { get; set; } public string MovedCol { get; set; } // 可选:导航属性关联TableA public ICollection<TableA> TableAs { get; set; } } // 修改后的TableA.cs public class TableA { public int Id { get; set; } public string Cola1 { get; set; } public string Cola2 { get; set; } // 新增外键字段 public int TableBId { get; set; } // 可选:导航属性关联TableB public TableB TableB { get; set; } // 移除原MovedCol字段 // public string MovedCol { get; set; } }
在DbContext中添加对应的DbSet:
public class AppDbContext : DbContext { public DbSet<TableA> TableAs { get; set; } public DbSet<TableB> TableBs { get; set; } // 其他DbContext配置... }
2. 生成初始迁移文件
在终端或Package Manager Console执行命令生成迁移:
# 终端命令 dotnet ef migrations add CreateTableBAndAddTableBId # Package Manager Console命令 Add-Migration CreateTableBAndAddTableBId
打开生成的迁移文件(位于Migrations目录下),此时自动生成的代码包含创建TableBs表、给TableAs添加TableBId字段的操作。
3. 手动添加数据迁移逻辑
在迁移文件的Up方法中,按顺序补充数据迁移的SQL语句,确保在创建表和添加字段后执行:
public partial class CreateTableBAndAddTableBId : Migration { protected override void Up(MigrationBuilder migrationBuilder) { // 自动生成:创建TableB表 migrationBuilder.CreateTable( name: "TableBs", columns: table => new { Id = table.Column<int>(type: "int", nullable: false) .Annotation("SqlServer:Identity", "1, 1"), Colb1 = table.Column<string>(type: "nvarchar(max)", nullable: true), Colb2 = table.Column<string>(type: "nvarchar(max)", nullable: true), MovedCol = table.Column<string>(type: "nvarchar(max)", nullable: true) }, constraints: table => { table.PrimaryKey("PK_TableBs", x => x.Id); }); // 自动生成:给TableA添加TableBId字段(先设默认值,后续更新) migrationBuilder.AddColumn<int>( name: "TableBId", table: "TableAs", type: "int", nullable: false, defaultValue: 0); // 手动添加:将TableA的MovedCol数据插入TableB(Colb1/Colb2按实际业务赋值) migrationBuilder.Sql(@" INSERT INTO TableBs (Colb1, Colb2, MovedCol) SELECT '', '', MovedCol FROM TableAs "); // 手动添加:关联TableA与TableB(按自增Id顺序匹配,需根据业务调整关联逻辑) migrationBuilder.Sql(@" UPDATE ta SET ta.TableBId = tb.Id FROM TableAs ta JOIN ( SELECT Id, ROW_NUMBER() OVER (ORDER BY Id) AS RowNum FROM TableBs ) tb ON ta.Id = tb.RowNum "); // 手动添加:删除TableA的MovedCol字段 migrationBuilder.DropColumn( name: "MovedCol", table: "TableAs"); } protected override void Down(MigrationBuilder migrationBuilder) { // 回滚逻辑:先恢复TableA的MovedCol字段 migrationBuilder.AddColumn<string>( name: "MovedCol", table: "TableAs", type: "nvarchar(max)", nullable: true); // 回滚数据:从TableB将MovedCol写回TableA migrationBuilder.Sql(@" UPDATE ta SET ta.MovedCol = tb.MovedCol FROM TableAs ta JOIN TableBs tb ON ta.TableBId = tb.Id "); // 回滚表结构:删除TableB、移除TableA的TableBId字段 migrationBuilder.DropTable( name: "TableBs"); migrationBuilder.DropColumn( name: "TableBId", table: "TableAs"); } }
注意:数据关联的SQL语句需根据实际业务调整,比如
Colb1/Colb2的赋值规则、TableA与TableB的关联逻辑等。
4. 执行迁移
在终端或Package Manager Console执行命令应用迁移:
# 终端命令 dotnet ef database update # Package Manager Console命令 Update-Database
关键提示
- EF Core自动迁移不处理数据迁移,必须通过
migrationBuilder.Sql()手动编写数据迁移逻辑 - 务必完善
Down方法,确保迁移可以回滚 - 执行迁移前建议备份数据库,避免数据丢失
内容的提问来源于stack exchange,提问作者Myth Rush
相关产品推荐
相关产品推荐

