如何遍历 EF Core 迁移中的实体?

How to iterate through entities in EF Core migration?

我正在将 Identity 改装到现有项目中。我已经有 UsersRolesUserRoles table,所以这主要是在实际添加 [=47 之前调整 table 和列名=]身份 类,所以他们“接管”了那些table。

我遇到的问题如下。 UserEntity.Id是一个Guid,所以我需要从IdentityUser<Guid>继承UserEntity。但是 RoleEntity.Id 是一个 longIdentity 有一个奇怪的限制,即 User.IdRole.Id 类型必须匹配 - 至少在 AddIdentity<> 扩展方法中使用时。所以我需要将 RoleEntity.Id 的类型更改为 Guid。由于我已经有许多具有角色的用户,因此我必须调整 UserRoles table.

现在,为 Roles 创建一组新的 Id 不是问题,它们已播种,所以我只创建了一个新列 Roles.NewId类型 Guid 并用一些随机值填充它。我还创建了一个相应的列 UserRoles.NewRoleId(我将在应用 Identity 之前在另一个迁移中重命名它们,以便它们匹配)。我想要的是当 这个特定的 迁移运行时,来自 Roles.NewId 的值被复制到 UserRoles.NewRoleId,对应于现有的分配。

SQL 命令可能类似于

UPDATE UserRoles U SET NewRoleId = (SELECT NewId FROM Roles WHERE Roles.Id = U.RoleId)

但我在测试中使用内存数据库 (SQLite),在生产中使用 MariaDb,所以SQL 可能不匹配。由于此设置,我已经遇到了一些问题,但是 MariaDb 没有内存中提供程序。因此,如果我可以在某处插入以下循环,我会感觉更安全:

foreach (var ur in UserRoles)
{
  ur.NewRoleId = Roles.First(r => r.Id == ur.RoleId).NewId;
}
Save();

现在:

  1. 我在哪里可以插入那个循环,所以它只在这次迁移之后执行,而不是在每次迁移之后执行?
  2. 如何处理在下一次迁移中我将重命名一些列,然后删除旧的 IdRoleId 列的情况?

经过调查,我发现只有两个选择。

  1. 使用SQL。它不干净,没有 IntelliSense,但它会工作。

  2. 对于这种特殊情况,角色是种子,因此 role ids 在编译时是已知的。因此,可以通过为每个角色创建一个调用并在其中放置一个新的 Guid(pre-generated 和 hard-coded)来滥用 migrationBuilder.UpdateData

migrationBuilder.UpdateData(
    table: "UserRoles",
    keyColumn: "RoleId",
    keyValue: 1L,
    column: "NewRoleId",
    value: new Guid("11111111-1111-1111-1111-111111111111"));