带有 IdentityDbContext 和 hasData 种子的 EFcore 创建 IdentityRole

Roe*_*t M 2 c# entity-framework-core .net-core entity-framework-migrations

我有点眼花缭乱;我正在使用 dotnet core (2.1) EF 进行迁移。当我仅根据上下文创建第一个迁移时,实际上看起来一切正常。

所以我有一个类似的上下文:

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)
    { }
}
Run Code Online (Sandbox Code Playgroud)

所以在创建迁移后它想添加:

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.
Run Code Online (Sandbox Code Playgroud)

我以为一切都很好。

然后我开始关注下面的文章; 如何在 EF Core 2.1.0 中为管理员用户做种?

在设置HasData和播种数据库后,创建了一个新的迁移,它创建了一个新的迁移,它想要删除AspNetRoles表并创建为新表IdentityRole。我刚刚删除了数据库并尝试再次执行此操作,现在它只想在播种时插入数据。但我无法弄清楚我改变了什么,甚至更好,为什么它想要删除并创建不同的表。

有人可以解释一下它何时要创建AspNetRoles以及何时要创建IdentityRoles(以及与之配套的其他表)。

只是要确定; 上下文总是从

: IdentityDbContext<User, IdentityRole<Guid>, Guid>

和我的User

public class User : IdentityUser<Guid>
{
    public virtual ICollection<CountryUser> CountryUsers { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

谢谢!!

Iva*_*oev 5

据我了解,您正在遵循以下方法:

modelBuilder.Entity<IdentityRole>().HasData(new IdentityRole { Name = "Admin", NormalizedName = "Admin".ToUpper() });
Run Code Online (Sandbox Code Playgroud)

这段代码有两个问题。

首先是使用modelBuilder.Entity<IdentityRole>(). 这使得IdentityRoleEF Core将类视为实体,因此IdentityRoles它尝试创建表。这是因为IdentityRoleclass您的模型使用的不同 - IdentityRole<Guid>。将其更改为modelBuilder.Entity<IdentityRole<Guid>>()(以及new操作员),问题将得到解决。

第二个问题是HasData 需要指定 PK 值,如EF Core 文档的数据种子部分所述:

即使通常由数据库生成,也需要指定主键值。它将用于检测迁移之间的数据更改。

因此,除了更改HasData泛型类型参数之外,您还需要预先生成 Guid 以用作新角色的 Id(有关类似问题的更多详细信息,请参阅Entity Framework Core Auto Generated guid)并使用如下内容:

modelBuilder.Entity<IdentityRole<Guid>>().HasData(
    new IdentityRole<Guid>
    {
        Id = new Guid("pre generated value"),
        Name = "Admin",
        NormalizedName = "Admin".ToUpper()
    }
);
Run Code Online (Sandbox Code Playgroud)