So I've ran into an issue that I am not sure how to handle. You see I am trying to deal with an Initial seeding of Admin data for my App. But the thing is.. Since I am using Identity to handle both the Users and Roles within my Application. In order to seed them I have to use the UserManager and RoleManager to properly seed and assign said data to the database.
For the UseAsyncSeeding() there ain't no problem since both UserManager and RoleManager have async methods.
But after reading a bit of the documentation I realized that it is highly advisable to have both UseSeeding and UseAsyncSeeding even when you are just going to be using one of them. Specially if you are handling migrations through the .NET CLI. Which I am.
And that happens to be an issue since UserManager and RoleManager don't have synchronous methods. Or at least I don't think they have.
How then could I handle this issue? How can I properly seed data using these methods and Identity?
In case you want to see the code this is how I am doing it within the UseAsyncSeeding()
optionsBuilder.UseAsyncSeeding(async (ctx, _, ct) =>
{
// Services
var userManager = ctx.GetService<UserManager<Usuario>>();
var roleManager = ctx.GetService<RoleManager<IdentityRole>>();
//Persona Data
var personaAdminExist = await ctx.Set<Persona>().FirstOrDefaultAsync(p => p.Carnet == _adminData.PersonalInformation.Carnet);
if (personaAdminExist != null) throw new Exception("Persona Admin Data Already Exists");
var newPersonaAdmin = await ctx.Set<Persona>().AddAsync(adminPersonaData);
//Usuario Data
var usuarioAdminExist = await userManager.FindByNameAsync(_adminData.Username);
if (usuarioAdminExist != null) throw new Exception("Usuario Admin Data Already Exists");
var newUsuarioAdmin = await userManager.CreateAsync(adminUsuarioData);
if (!newUsuarioAdmin.Succeeded) throw new Exception("Error while creating Usuario");
await ctx.SaveChangesAsync(ct);
// Role Data
var usuarioAdmin = await userManager.FindByNameAsync(_adminData.Username);
var usuarioRoleExists = await roleManager.FindByNameAsync(adminRole.Name);
if (usuarioAdminExist != null) throw new Exception("Admin Role Data Already Exists");
var newUsuarioRole = await roleManager.CreateAsync(adminRole);
if (!newUsuarioRole.Succeeded) throw new Exception("Error while Creating new Role");
var roleAssignated = await userManager.AddToRoleAsync(usuarioAdmin!, adminRole.Name);
// Assignation of roles
if (!roleAssignated.Succeeded) throw new Exception("Error while Assignating Role");
await ctx.SaveChangesAsync(ct);
});
It probably could be cleaner. But I was just figuring things out.
With that being said, any resource, guidance or advice into how to handle seeding within the .UseAsyncSeeding() and UseSeeding() methods when working with Identity would be highly appreciated.
Thank you for your time!
So I've ran into an issue that I am not sure how to handle. You see I am trying to deal with an Initial seeding of Admin data for my App. But the thing is.. Since I am using Identity to handle both the Users and Roles within my Application. In order to seed them I have to use the UserManager and RoleManager to properly seed and assign said data to the database.
For the UseAsyncSeeding() there ain't no problem since both UserManager and RoleManager have async methods.
But after reading a bit of the documentation I realized that it is highly advisable to have both UseSeeding and UseAsyncSeeding even when you are just going to be using one of them. Specially if you are handling migrations through the .NET CLI. Which I am.
And that happens to be an issue since UserManager and RoleManager don't have synchronous methods. Or at least I don't think they have.
How then could I handle this issue? How can I properly seed data using these methods and Identity?
In case you want to see the code this is how I am doing it within the UseAsyncSeeding()
optionsBuilder.UseAsyncSeeding(async (ctx, _, ct) =>
{
// Services
var userManager = ctx.GetService<UserManager<Usuario>>();
var roleManager = ctx.GetService<RoleManager<IdentityRole>>();
//Persona Data
var personaAdminExist = await ctx.Set<Persona>().FirstOrDefaultAsync(p => p.Carnet == _adminData.PersonalInformation.Carnet);
if (personaAdminExist != null) throw new Exception("Persona Admin Data Already Exists");
var newPersonaAdmin = await ctx.Set<Persona>().AddAsync(adminPersonaData);
//Usuario Data
var usuarioAdminExist = await userManager.FindByNameAsync(_adminData.Username);
if (usuarioAdminExist != null) throw new Exception("Usuario Admin Data Already Exists");
var newUsuarioAdmin = await userManager.CreateAsync(adminUsuarioData);
if (!newUsuarioAdmin.Succeeded) throw new Exception("Error while creating Usuario");
await ctx.SaveChangesAsync(ct);
// Role Data
var usuarioAdmin = await userManager.FindByNameAsync(_adminData.Username);
var usuarioRoleExists = await roleManager.FindByNameAsync(adminRole.Name);
if (usuarioAdminExist != null) throw new Exception("Admin Role Data Already Exists");
var newUsuarioRole = await roleManager.CreateAsync(adminRole);
if (!newUsuarioRole.Succeeded) throw new Exception("Error while Creating new Role");
var roleAssignated = await userManager.AddToRoleAsync(usuarioAdmin!, adminRole.Name);
// Assignation of roles
if (!roleAssignated.Succeeded) throw new Exception("Error while Assignating Role");
await ctx.SaveChangesAsync(ct);
});
It probably could be cleaner. But I was just figuring things out.
With that being said, any resource, guidance or advice into how to handle seeding within the .UseAsyncSeeding() and UseSeeding() methods when working with Identity would be highly appreciated.
Thank you for your time!
Share Improve this question asked 7 hours ago yzkaelyzkael 1959 bronze badges1 Answer
Reset to default 0The short answer for this is , you could use .Result to directly get the result for the async method to achieve your requimrent.
Like below:
Modify the var usuarioAdminExist = await userManager.FindByNameAsync(_adminData.Username);
to var usuarioAdminExist = await userManager.FindByNameAsync(_adminData.Username).Result;