Как перебирать сущности при миграции EF Core? - PullRequest
0 голосов
/ 03 августа 2020

Я переделываю Identity в существующий проект. У меня уже были таблицы Users, Roles и UserRoles, так что это в основном вопрос или корректировка имен таблиц и столбцов перед фактическим добавлением классов Identity , чтобы они «захватили» эти таблицы.

Проблема у меня следующая. UserEntity.Id - это Guid, поэтому мне нужно унаследовать UserEntity от IdentityUser<Guid>. Но RoleEntity.Id - это long. Identity имеет то странное ограничение, что типы User.Id и Role.Id должны совпадать - по крайней мере, при использовании в методе расширения AddIdentity<>. Поэтому мне нужно изменить тип RoleEntity.Id на Guid. И поскольку у меня уже есть несколько пользователей с ролями, мне нужно настроить UserRoles таблицу.

Теперь создание нового набора Id s для Roles не проблема, они заполнены, поэтому я просто создал новый столбец 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 нет провайдера в памяти. Таким образом, я чувствовал бы себя в большей безопасности, если бы мог вставить где-нибудь следующий l oop:

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

Now:

  1. Где я могу вставить это l oop, так что это только выполняется после этой миграции, а не после каждой?
  2. Как справиться с ситуацией, когда при следующей миграции я переименую несколько столбцов, а позже я отброшу старые Id и RoleId столбцы?

1 Ответ

0 голосов
/ 15 августа 2020

Изучив это, я нашел только два варианта.

  1. Используйте SQL. Это не чисто, нет IntelliSense , но он будет работать.

  2. В этом конкретном случае роли засеваются, поэтому role id s известны во время компиляции. Таким образом, можно злоупотреблять migrationBuilder.UpdateData, создавая по одному вызову для каждой роли и помещая туда новый Guid (предварительно сгенерированный и жестко запрограммированный).

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

...