I am a bit dazzled; I am using dotnet core (2.1) EF with migrations. When I create the first migration just based upon the context, it all looks OK actually.
so I have a context like:
public class DataContext : IdentityDbContext<User, IdentityRole<Guid>, Guid>
{
public virtual DbSet<Country> Countries { get; set; }
public virtual DbSet<CountryUser> CountryUsers { get; set; }
//..more stuff
public DataContext(DbContextOptions options) : base(options)
{ }
}
so after creating the migrations it wants to add:
migrationBuilder.CreateTable(
name: "AspNetRoles",
columns: table => new
{
Id = table.Column<Guid>(nullable: false),
Name = table.Column<string>(maxLength: 256, nullable:
//etc. etc. Removed rest of migrations.
All good I thought.
Then i started to follow the following article; How to seed an Admin user in EF Core 2.1.0?
After setting the HasData
and seeding the DB, created a new migration, it created a new migration where it wanted to drop the AspNetRoles
table and creates as new table IdentityRole
.
I just deleted the DB and tried to do it again, and now it only wants to insert the data when seeding. But i cannot figure out what I changed and even better, why it wanted to drop and create different tables.
can somebody explain when it wants to create AspNetRoles
and when it wants to create IdentityRoles
(and along the other tables that goes with it).
Just to be sure; the context was always extending from
: IdentityDbContext<User, IdentityRole<Guid>, Guid>
and my User
:
public class User : IdentityUser<Guid>
{
public virtual ICollection<CountryUser> CountryUsers { get; set; }
}
thnx!!
As I understand, you are following the following approach:
modelBuilder.Entity<IdentityRole>().HasData(new IdentityRole { Name = "Admin", NormalizedName = "Admin".ToUpper() });
There are two problems with this code.
The first is the usage of modelBuilder.Entity<IdentityRole>()
. This makes IdentityRole
class to be treated by EF Core as an entity, hence the IdentityRoles
table it tries to create. It's because IdentityRole
class is different from what your model is using - IdentityRole<Guid>
. Change it to modelBuilder.Entity<IdentityRole<Guid>>()
(and also the new
operator) and the problem will be solved.
The second problem is that HasData
requires PK values to be specified, as explained in the Data Seeding section of the EF Core documentation:
The primary key value needs to be specified even if it's usually generated by the database. It will be used to detect data changes between migrations.
So additionally to changing the HasData
generic type argument, you need to pre generate Guid to be used as Id for the new role (see Entity Framework Core Auto Generated guid for more details a the similar issue) and use something like this:
modelBuilder.Entity<IdentityRole<Guid>>().HasData(
new IdentityRole<Guid>
{
Id = new Guid("pre generated value"),
Name = "Admin",
NormalizedName = "Admin".ToUpper()
}
);